How to deserialize another implementation of an interface using wcf

The following situation:

Our software works with business objects, currently they are sent from wcf from server to client.

[Serializable] public class SomeValueBO { public DateTime Timestamp{ get; set; } } 

They are packed in request / response messages.

 [DataContract] public class Response { [DataMember] public List<SomeValueBO> Values { get; set; } } 

Problem:

We want to send the DTO to the client instead of the business object. I heard that on the client you can get an instance of another type that was sent to the server.

Example:

 public interface ISomeValue { DateTime Timestamp { get; set; } } [Serializable] public class SomeValueBO : ISomeValue { public DateTime Timestamp { get; set; } } [DataContract] public class SomeValueDTO : ISomeValue { [DataMember] public DateTime Timestamp { get; set; } } 

The answer will look like this:

 [DataContract] public class Response { [DataMember] public List<ISomeValue> Values { get; set; } } 

On server:

 public class ServiceClass : IService { public Response HandleRequest(Request request) { Response response = new Response(); response.Values.Add(new SomeValueBO()); return response; } } 

On the client:

 Response response = serviceProxy.HandleRequest(request); ISomeValue value = response.Values[0]; value is SomeValueDTO 

I tried this with the declaration of only the known DTO object type and equivalent data equivalence, but WCF still retains the deserialization of the element as an instance of BO.

I need to add that both paths should work by sending BO and retrieving them as BO, and sending BO and retrieving DTO, but of course with different requests.

So my question is: is this possible, and if so, what am I doing wrong?

Thanks for the help, Enyra

Edit: I also found out that we are using NetDataSerializer, maybe the problem is that it does not work?

+4
source share
2 answers

From MSDN :

NetDataContractSerializer differs from DataContractSerializer in one important way: NetDataContractSerializer includes CLR types in serialized XML, whereas DataContractSerializer does not. Therefore, NetDataContractSerializer can only be used if both serialization and deserialization end with the same CLR types.

That is why it is not working right now.

If you use the DataContractSerializer instead, the client and the service only need to agree on the serialized representation of the XML state of the object, not the exact type of the CLR. You will need to attribute the types of the parties with the DataContractAttribute in order to get the XML namespace associated with the serialized view on both sides. And, obviously, data contracts should be equivalent in terms of a serialized structure.

However, what you are trying to do should be workable with the DataContractSerializer . As for whether this is the best way β€” like all design decisions, β€œit depends.”

+2
source

Even if you have not used the NetDataContractSerializer (comment), the fact that SomeValueBO not declared as a data contract means that it will act mainly as a field serializer. This, in particular, is a pain, because automatically realized properties are serializers of royal pain in the field - they become insanely fragile.

I declare as a contract:

 [DataContract] public class SomeValueBO { [DataMember] public DateTime Timestamp{ get; set; } } 

and switch to the DataContractSerializer , but note that this is a violation of the change - you will have to update all clients and servers at the same time. Then you can have alternative implementations if they share the full signature of the contract.

Reusing NetDataContractSerializer - if it's for performance, there are alternatives - there are contract-based binary serializers that are faster (CPU) and smaller (bandwidth) than NetDataContractSerializer : Serialization performance tests used by WCF bindings

+4
source

Source: https://habr.com/ru/post/1340285/


All Articles