WCF DataContract Exclude DataMembers From Being Serialized In Derived Classes
I have a base class with DataMember properties in it. I also have a derived class with DataMember properties in it. In my WCF project I am returning the derived class. Is there a way for me to prevent a member in my base class from serializing? Here is some sample code:
public class BaseClass
{
public string ShortDescription {get;set;}
public string LongDescription {get;set;}
}
public class DerivedClass : BaseClass
{
public List<Description> Descriptions {get;set;}
}
In this code I want to be able to hide the inherited members ShortDescription and Lo开发者_开发技巧ngDescription because they are now obsolete. Any attempts to do so have been unsuccessful. Here is what I have tried:
public class DerivedClass : BaseClass
{
[DataMember]
public List<Description> Descriptions {get;set;}
// override the base class members
[IgnoreDataMember]
public override string ShortDescription {get;set;}
[IgnoreDataMember]
public override string LongDescription {get;set;}
}
and
public class DerivedClass : BaseClass
{
[DataMember]
public List<Description> Descriptions {get;set;}
// shadow the base class members
[IgnoreDataMember]
public new string ShortDescription {get;set;}
[IgnoreDataMember]
public new string LongDescription {get;set;}
}
Neither of these approaches have worked. The "DerivedClass" type when output to the WSDL still contains the "Ignored" members of the base class type.
You may wonder why I'm not just changing the base class. This is because I still use the base class in its original form as the previous version of the type for the WSDL to support backwards compatibility for consumers. In this way I can have a v1000 call that returns BaseClass and a V1010 call that returns a DerivedClass. I can add and change functionality to the DerivedClass all I want without the potential for affecting consumers of the v1000 functionality.
Try adding the [DataContract] attribute to both classes. This will tell the serializer to look at the [DataMember] and [IgnoreDataMember] attributes. Without the class being attributed with [DataContract], all public members are serialized.
[DataContract]
public class BaseClass
{
[IgnoreDataMember]
public string ShortDescription {get;set;}
[IgnoreDataMember]
public string LongDescription {get;set;}
}
[DataContract]
public class DerivedClass : BaseClass
{
[DataMember]
public List<Description> Descriptions {get;set;}
}
Also, it would be even better to add a namespace to your datacontracts by specifying it in the [DataContract(Namespace="...")] attribute. That would break old clients calling your updated service.
Eventually I found a suitable way to handle this task. I don't have the code in front of me so I'm going to wing the syntax. It's a pretty simple solution, but it solves the specific issue I was having.
public class BaseClass
{
// leave this guy empty
}
public class DerivedClassVersion1 : BaseClass
{
[DataMember]
public string ShortDescription {get;set;}
[DataMember]
public string LongDescription {get;set;}
}
public class DerivedClassVersion2 : BaseClass
{
[DataMember]
public List<Description> Descriptions {get;set;}
}
Badda bing! Pretty simple, but it's what I needed.
Try this:
public class BaseClass
{
[DataMember]
public virtual string ShortDescription {get;set;}
[DataMember]
public virtual string LongDescription {get;set;}
}
public class DerivedClass : BaseClass
{
[DataMember]
public List<Description> Descriptions {get;set;}
public override string ShortDescription {get;set;}
public override string LongDescription {get;set;}
}
EDIT: Perhaps utilizing message contracts to precisely control the serialization could work: http://msdn.microsoft.com/en-us/library/ms730255.aspx
Otherwise, you can also look into implementing a 'WCF Router' which would allow you to use the same endpoint, but route different versions to different services.
精彩评论