I have an exception when I want to send a devExpress session in a composite type in WCF.
I tried to make it serializable but I still get the error
information: Type System.Data.SqlClient.SqlConnection with data
contract name
SqlConnection:http://schemas.datacontract.org/2004/07/System.Data.SqlClient
is not expected. Consider using a DataContractResolver if you are
using DataContractSerializer or add any types not known statically to
the list of known types - for example, by using the KnownTypeAttribute
attribute or by adding them to the list of known types passed to the
serializer.
This the DataContract That I used.
[DataContract]
[Serializable]
[ServiceKnownType(typeof(Session))]
[ServiceKnownType(typeof(SqlConnection))]
[ServiceKnownType(typeof(SqlParameter))]
public class CompositeType
{
Session sValue ;
[DataMember]
public Session SessionValue
{ get {return sValue; } set {sValue = value; } }
}
I use also a method that send this class as parameter
void GetDataUsingDataContract(CompositeType composite);
XPO objects are tied to the data store via Session and you cannot send them over the wire.
If you want just to transfer raw data between computers, use a Data Transfer Object. XPO will retrieve data from the database on one side, and you will retrieve the data on the other side using WCF client methods.
XPO also supports a more complex scenario. If you want to use XPO on the client side but cannot create a direct database connection for security reasons, you can implement the IDataStore interface as a contract on the WCF side.
It is easy to implement the IDataStore interface, because all you need is to wrap an existing Data Store Adapter. All Data Store Adapters implement the IDataStore interface. XPO's Data Access Layer can use any IDataStore as a data source. This blog explains this approach: XPO is good for distributed applications.
Moreover, XPO has built-in WCF service and client components that already implement the IDataStore interface. All you need is to put them together. See examples here: Transferring Data via WCF Services.
Related
If i define a Test object, with string and Datetime properties and use it to return IEnumerable(T) collection in WCF
[OperationContract]
IEnumerable<Test> GetTestNotes();
and when calling the service from the client, I see that it is converting the IEnumerable to Test[]:
public Test[] GetTestNotes() {
return base.Channel.GetTestNotes();
}
And Im able to get data.
Question is: How reliable is it to use IEnumerable(T) interface rather than concrete, List(T)?
My clients that consume these WCF services are not only in .NET but also in JAVA.
If you're using the Visual Studio generated service references, you can pick what type is used for collections. Right-click on the service under Service References and select Configure Service Reference…. You should see these options:
However, this still won't allow you to select IEnumerable<T>. If you want tighter control over what the client interface looks like, your best bet is to define the contracts in a separate assembly and then reference those assemblies on both the client and server.
In the AppHost I'm setting JsConfig.ExcludeTypeInfo=true; to prevent the type being serialized into the response (I'm using anonymous types in some web service responses).
Everything works fine authenticating to /api/auth/credentials but when there is a request to a secured web service the GetSession() extension method fails to get the IAuthSession from ICacheClient because is trying to deserialize to an interface (IAuthSession) and in Redis the JSON doesn't have type information because of the JsConfig.ExcludeTypeInfo setting so the serializer doesn't know which concrete type to use.
If you use a CustomAuthUserSession and have
JsConfig.Init(new Config {
ExcludeTypeInfo = true
});
The solution is to enable it for the types that need it, in this case:
JsConfig<CustomAuthUserSession>.IncludeTypeInfo = true;
This is happening because ServiceStack lets you use and persist your own Custom UserSession it needs to persist that __type info with the payload to know what concrete type to dehydrate it into.
Supporting arbitrary responses
This is fairly rare as we only need to do this when a DTO can support holding arbitrary types, basically when using object, interfaces or abstract properties (i.e. we can't infer the type from the class definition). The only other place this exists in ServiceStack is in the MQ Message<T> type which allows persisting of any arbitrary body.
Use loose-typed data structures instead of anonymous types
By default, ServiceStack only adds the added __type info when it's required, although ideally you shouldn't be using anonymous types in service responses which requires deviating from the default configuration and the "pit of success" development that ServiceStack encourages.
Using a loose-typed data structure like Dictionary or List is preferred for unstructured data as anonymous types basically prevent your DTO's from being deserializable, and prevents clients from having any idea of what the service ultimately returns - which will break anything that relies on your services from being statically inferable, e.g. XSDs/WSDLs/SOAP.
Is it possible to send objects through RoutingService to peer WCF services without having the router know about the exact type of these objects ?
My intention is to create a router once for all, then be able to add new WCF services, dynamically add them to the routing table, and allow clients to communicate with these services without having to stop, change the code of the router, then start it again.
I was thinking of a generic contract like this:
[DataContract]
public class RequestObject
{
}
[DataContract]
public class ReplyObject
{
}
[ServiceContract]
public interface IGenericServiceInterface
{
[OperationContract]
ReplyObject DoJob(string jobType, RequestObject request);
}
I could put this in a common library that all 3 components link to (client, router, services). But, I am not sure, it will be possible to derive new sub classes to allow new clients/services with new data exchanges to be added without having to change the router.
Any advise ? is it possible for the solution to work when encryption is enforced through clients till services ?
Thanks in advance.
There's a good msdn on using the Message class in WCF to build contract agnostic endpoints. Does not use routing service, but you could build a router using this:
http://msdn.microsoft.com/en-us/library/ms734675.aspx
I have the following scenario:
There is a complex object that is residing in the standalone class library and some of the object properties have default values.
The object is argument for WCF public method.
I instantiate this object on the client of WCF, assign values to properties and pass it to the WCF public method.
The WCF method on service side accepts it and does whatever.
My problem is that when I instantiate the object on the client property default values are not available for me to use and I have to assign them in code again.
I looked through the past questions on the topic here and did not find anything related to my scenario. I don't really have data contract for the argument although on the client my object gets instantiated not from the class library itself but from the service reference, like WCFServiceReference.MyClass (otherwise WCF method can not accept it as argument).
I would really like to have all those default values to be available on the client.
I would appreciate any assistance.
Thanks!
With your approach -- using the service proxy classes -- the client only gets the properties marked with DataMember. That's why the default values you assign don't appear in the client -- that code is not serialized, so it's not sent with the WCF service.
If you want to share code, you can do it by declaring your DataContract classes in a separate class library. Have the WCF service and the client both reference that library.
We are using C#, ASP.NET & WCF. I am trying to send form data to a web service which in turn inserts/updates a database with the data from my form. How should I send over my data?
We have the forms populated fine but are having some issues with sending updates back to the web service. We have determined that it is not great practice to use datasets in this situation, it is slow and we have to do too many SELECT *'s for our liking.
I have about 15 fields that need to go across. One team member wants to pass everything as a parameter which I dont think is optimal. We tried sending everything across in an Object[] array but are receiving a weird error "Type 'System.DBNull' with data contract name 'DBNull:http...' is not expected. Add any types not known statically to the list of known types",
Any suggestions are most welcome.
We use WCF to define our Data Contracts and Data Methods using attributes.
Basically we create an assembly to define all our classes and another assembly to provide the WCF connective bits
OPur class assembly contains a service class and several message classes.
We define an interface for our service and mark it up with relevant WCF markup. This is our Service Contract.
[ServiceContract]
public interface IExampleWebService
{
[OperationContract]
CreateAccountResponse CreateAccount(int parameter, CreateAccountArguments another parameter);
[OperationContract]
DeleteAccountResponse DeleteAccount(int parameter);
}
We implement this interface in a class and we create various data contracts (our response and argument classes).
[DataContract]
public class CreateAccountResponse
{
[DataMember]
public bool CreatedOk { get; set; }
[DataMember]
public int AccountId { get; set; }
}
These classes are exposed to our form using the Web Service (We create another assembly as a web service and have a class that inherits from our Service Class (not shown in this example) so we let Visual Studio do all the work setting up the WCF service as we reap the benefits with an easy to use and maintain Web Service.