Freigeben über


Extending Data Contracts

So let's say you're working on a WCF app and following a contract-first driven development model and autogenerating your data contracts based on XSD schema definitions. Svcutil does a reasonable job of creating your data contract classes. Curiously, collection type classes are autogenerated without any partial statement in the class declaration (more on this later). Non-collection types are created with a partial class declaration. For example, here's a declaration of a data contract (it was generated using the .NET 3.0 framework): 

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Namespace="https://www.mycompany.com/20080910/BusinessItemDataContract")]
[System.SerializableAttribute()]
public partial class BusinessItemDataContract : object, System.Runtime.Serialization.IExtensibleDataObject

This allows us to create extended classes using another file. When the BusinessItemDataContract is regenerated the partial class code in the separate file will remain. This can be used on the server side to adjust values before sending data over the wire. Or, additional values can be added to the data contract and serialized if a DataMember attribute is added. This could be useful when the contract (i.e. the XSD) is provided by another WCF service and you want to embellish it with additional business data before returning it to the client. For example:

public partial class BusinessItemDataContract
{

[DataMember]
public string ClientNumber
{
  get { return _clientNumber; }
  set { _clientNumber = value; }
}

The DataMember attribute is not required by default. Keep it that way. If the DataMember is marked as Required then call the service returning the original BusinessItemDataContract will fail as the return contract will not contain the new ClientNumber data member. It adheres to the original definition of the BusinessItemDataContract XSD which does not contain this new element.

Collection type data contracts are not so easily extended - and for good reason. An autogenerated collection type DataContract looks like:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")][System.Runtime.Serialization.CollectionDataContractAttribute(Namespace="https://www.mycompany.com/20080910/BusinessItemCollection", ItemName="BusinessItemDataContract")]
[System.SerializableAttribute()]
public class BusinessItemCollection : System.Collections.Generic.List<BusinessItemContract>

Autogenerated code for a collection type contract uses a CollectionDataContract attribute to drive the serialization process of the contained items, in this case the BusinessItemDataContrect, and not the collection itself. So, even if we modified the autogenerated class to make the it a partial class any DataMember properties would not be serialized. Further, any manual updates to an autogenerated class would need to be reapplied after the next time the class is regenerated.

CollectionType data contracts are well documented here if you’d care to look further:
https://msdn.microsoft.com/en-us/library/aa347850(VS.85).aspx