Passing Object as a parameter to a WCF Service - wcf

I have a method AddEntity(object o). I am figuring out which entity type it is on the server side using reflection and such and adding it to the database. I am using Self Tracking entities. However this is the error I am getting.
"Element contains data from a type that maps to the name . The deserializer has no knowledge of any type that maps to this name."
This is a lie. I have the entity on the server side, and I have the entity on the client side as a proxy. I am just passing it as an object because I have generalized the AddEntity method.
I am using object because generics are not serializable. So I cannot do something like this:
[OperationContract]
AddObject(T entity)
Any suggestions are most welcome.

No. This is not how the WCF works. WCF serializes entity to wire format and deserializes the entity on the other side. Deserialization process needs to know what type have to be deserialized - such information is not part of serialized data. This type is resolved from operation parameter or return type. Object is not allowed.

Related

Pass polymorphic type as argument in SoapUI when using ServiceKnownType in WCF Service

I have a WCF Service; this service has an operation that receives an argument of type Request. This is only the base type, and when calling the operation we actually send a value of type Request_V1 (which inherts from Request), that has the complete implementation of the request I want to send.
When trying to test the service using soapUI, I'm able to create the complex type of type Request_V1 (adding the proper namespace) but for some reason, the service is receiving the value as if it were of Request type.
Reading about ServiceKnowType, I found out here that I need to specify somehow explicitly in the client this inheritance relationship, but I haven't found any info regarding how to do it on soapUI
Has anybody experienced and solved the same issue?
Thanks
You also have to specify the type in the SOAP message.
For example
<Request i:type="d:RequestV1">
...
where i is defined as XML-Instance namespace
On service side, you need to typecast to specific derived type.
operation (Request request){
if(!(request is Request_V1)){
throw Excetion("Unknown type!");
}
var request_v1 = Request as Request_V1;
// use request_v1
}
On SOAP UI side, specify type as below:
<soapenv:Body xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ns1:OperationName>
<ns1:request i:type="ns2:Request_V1">
Make sure you have defined ns1 and ns2 before referring to them.
You don't specify the inheritance in the client, rather in the service. SOAPUI shouldn't have a problem with that. Check you have the correct declarations on your data contracts. This might help - Deserialize Abstract Class.

Database entity exposed as object in WCF service

I have a WCF service in which I have a method which returns an IQueryable of an object representing a database table (Accommodation) using Entity Framework. When I try and use that method on the client side the method does not return IQueryable but object. I looked at the code for the service and the Accommodation class that Entity Framework generates has this attribute
[DataContractAttribute(IsReference=true)]
So, AFAIK the client should be able to see that class. What is going wrong here?
Thanks,
Sachin
The type will only appear in the metadata if it is used on the contract. The metadata has no idea what IQueryable is - its a definition of behavior whereas the contract only defines state so the generated code will use somethingit does understand in this situation - i.e. object
It is really not a good idea to use the EF generated types on your service contract - you, in effect, tightly couple your service consumers to your data access layer. Use EF internally in the service and use types which define the data you want to pass around on the service boundary

Entity Framework T4 POCO objects raising exception in WCF

These objects have collections of type ICollection<>
If I pass an object graph from client to server it throws the following exception:
System.NotSupportedException was unhandled by user code
Message=Collection was of a fixed size.
Source=mscorlib
Which is occurs in the fixup code the T4 template has generated. It seems the collections are being deserialized on the server as arrays and so can't be modified. Is there a way to specify the type the serializer should use?
I would strongly recommend that you don't use the POCO classes on your service boundary. Create a separate set of classes to model the data you want to send and receive across the wire (Data Transfer Objects - DTOs) and use a tool like automapper to move data between the DTOs and your POCO classes
Essentially you end up tying the consumers of your service to your service's internal conceptual model which means you become constrained in changing your implementation because you need to avoid breaking your clients
Try using the following attribute
[ServiceKnownType(typeof(List<string>))]
If that doesn't work, perhaps try using IList<T> if that is possible in your situation

Generic DataContract in Agatha WCF

I am trying to use Generic DataContract class so that I don't have to implement several types for a collection of different objects.
Exp :
I have a Profile object which contains a collection of objects.
So I want to have one Profile<Foo> and Profile<Foo1> where profile contains a collection of Foo or Foo1 objects.
I have been reading that WCF does not support generic classes and actually the error that I get is the following.
Type 'GL.RequestResponse.ProfileResponse1[T]' cannot be exported as a schema type because it is an open generic type. You can only export a generic type if all its generic parameter types are actual types.`
Now the ProfileResponse is this Profile object that I am trying to use.
Now in my host I am doing the following. :
ServiceConfig(typeof(ProfileHandler<EducationResponse>).Assembly,
typeof(ProfileRequest).Assembly,
typeof(Container)).Initialize();
This is dhe definition of the handler with the datacontract.
public class ProfileHandler<T> : RequestHandler<ProfileRequest,
ProfileResponse<T>>
The Container is using Windsor Container to register the objects.
The registration works fine but after I instantiated the Service Host for WCF processor, and call Open Method of the host I get the above error.
Is there really no way for me to write generic response requests for wcf with agatha ?
It feels like such a waste to have to define a Profile container class for each type being contained in that collection.
thanks.
One cannot have open generic handlers, because the server side needs to know what the type is.
One can use so called closed generic methods. This way the server side knows the types for witch to load the handler.
Also, one could potentially configure Agatha so that it allows to receive extra information related to the request. In this case, it would be the type wrapped in the response.
One could do this by defining a a BaseRequest class and having all the request extend this class. This class can have a property which takes the type of the response. Or the type to be wrapped in the response.
In the process, when examining the request, the process can get the type to be wrapped in the Response, so that i knows how to load the class.
I have not implemented this, since it would take too much time and I am not sure I want to be responsible for maintaining Agatha for our application, but this is how I would do it.

Are there any specific complex types that can't be returned by a WCF Service?

I have a question on the types that can be returned by a WCF service.Are there any specific complex types that can't be returned by a WCF service? To put more clearly, can we have any kind of complicated datatypes to be defined as Data Contracts and have them returned by the Service operations? Is there any limitation to any type?
Yes - anything that cannot be serialized into a message constrained by a XML schema file.
This includes:
interfaces (only concrete types)
generics
any data structure that doesn't just contain data, but also behavior (like a SqlConnection or something like that)
the Windows API primitives, like a Brush or other drawing elements
The main point is: whatever you're trying to send from client to server must be able to be serialized into an XML message, expressed in a XML schema, and deserialized back into a new object