How to serialize a derived type as its base type with WCF
Asked Answered
R

2

14

I have a common library with some objects in it. Then I have a service project that references the common library and creates some derived types from objects in the common library.

I want my service to serialize the derived types as their base types defined in the common library.

I cannot use KnownTypes on the objects in the common library because I don't want the common library referencing the service assemblies.

So how can I have wcf serialize the derived types as their base types?

I wish I could do something like...

[DataContract(SerializeAsType = typeof(BaseType))] public class DerivedType : BaseType { }

Is anything like this possible?

Residentiary answered 10/11, 2010 at 3:16 Comment(0)
H
3

Are you using .NET 4.0? You can use the DataContractResolver for this if you are:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractresolver.aspx

This is also basically what Entity Framework 4.0 does for its DataContractResolver for proxy types.

Here is an example: Link

(see DeserializeAsBaseResolver in the link).

EDIT: If you're not using .NET 4.0, I think your next best option is a DataContractSurrogate: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx. ...so you can control the serialization by hand, but this can get messy.

Both are passed into the constructor of your DataContractSerializer and can be configured for WCF via the DataContractSerializerOperationBehavior: http://msdn.microsoft.com/en-us/library/system.servicemodel.description.datacontractserializeroperationbehavior.aspx.

Hellenhellene answered 10/11, 2010 at 3:25 Comment(1)
I'm using 3.5, so I had to go with the surrogate option... And it worked great! ThanksResidentiary
F
8

We have just "solved" this issue by setting inherited class [DataContract(Name="BaseClass")]. It works even if inherited class is internal and defined in another project.

Hope it helps.

Formica answered 12/11, 2010 at 9:26 Comment(4)
Hi marc. Was this all you did? Can we have a fuller example?Excoriate
Yes, this was all what was needed to be done. Just rename contract to the name of base class.Formica
+1 For me this was by far the easiest solution. Its a one liner that works. The DataContractResolver approach is long and involves classes and inserting the resolver server host etc. Its only redeeming feature is that you can control the behaviour on a contract method by method basis - where this Name= solution applies to all instances of transport of this object (in my case that was ok).Manipulator
Just to point out this doesn't work if you have multiple known derived types of the base class. In this instance you also have to declare a separate NameSpace for each of the derived types. Which plays havoc with attempting to build generic Xpaths maps down to the common items.Externalism
H
3

Are you using .NET 4.0? You can use the DataContractResolver for this if you are:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractresolver.aspx

This is also basically what Entity Framework 4.0 does for its DataContractResolver for proxy types.

Here is an example: Link

(see DeserializeAsBaseResolver in the link).

EDIT: If you're not using .NET 4.0, I think your next best option is a DataContractSurrogate: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx. ...so you can control the serialization by hand, but this can get messy.

Both are passed into the constructor of your DataContractSerializer and can be configured for WCF via the DataContractSerializerOperationBehavior: http://msdn.microsoft.com/en-us/library/system.servicemodel.description.datacontractserializeroperationbehavior.aspx.

Hellenhellene answered 10/11, 2010 at 3:25 Comment(1)
I'm using 3.5, so I had to go with the surrogate option... And it worked great! ThanksResidentiary

© 2022 - 2024 — McMap. All rights reserved.