Here are 2 solutions
Solution No. 1:
I had the same issue, and so I graced my DataContract class with the DataMember members as you mentioned. HOWEVER, I do not like to edit automatically generated code directly, because I have to repeat it every time I regenerate the file. To get around this, I used the MetadataType attribute. In your case, it will look like this ...
First, you save the automatically generated object as is:
public partial class Comment { public int CommentId { get; set; } public string Content { get; set; } public System.DateTime Posted { get; set; } public bool Approved { get; set; } public int AnswersTo { get; set; } public int PostId { get; set; } public virtual Post Post { get; set; } }
Next, in another file, you will create another partial class and decorate it as follows:
[MetadataType(typeof(Metadata))] [DataContract(IsReference = true)] public partial class Comment { private class Metadata { [DataMember] public int CommentId { get; set; } [DataMember] public string Content { get; set; } [DataMember] public System.DateTime Posted { get; set; } [DataMember] public bool Approved { get; set; } [DataMember] public int AnswersTo { get; set; } [DataMember] public int PostId { get; set; } [DataMember] public virtual Post Post { get; set; }
MetadataType will essentially add the attributes from the Metadata buddy class to those of the same name in Comment (not directly, but for our purposes it is close enough ... which is the topic for another after). Of course, if your Comment object changes, you will need to update it accordingly.
Solution No. 2:
When you change your second file every time you make changes, this is only a slight improvement from directly editing automatically generated files. Fortunately, there is another approach that is much easier to maintain. Details can be found here , but as a summary, all you need to do is decorate your OperationContract , which consumes Comment with the optional ReferencePreservingDataContractFormat attribute. Please note that there is a small error in the code presented on this page that will lead to infinite recursion. As noted in this post, the fix is ββpretty simple: instead of recursing at all, just create a new DataContractSerializer
The advantage of this approach is that no matter how much you change Comment , you still don't need to update anything.
As an example for your code, suppose you use Comment as follows:
[OperationContract] Comment FindComment(string criteria);
All you have to do is add
[OperationContract] [ReferencePreservingDataContractFormat] Comment FindComment(string criteria);
And then in another place you need to define a ReferencePreservingDataContractFormat , which will look like this:
//From http://blogs.msdn.com/b/sowmy/archive/2006/03/26/561188.aspx and /questions/799848/endless-loop-in-a-code-sample-on-serialization public class ReferencePreservingDataContractFormatAttribute : Attribute, IOperationBehavior { public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) { } public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy) { IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description); innerBehavior.ApplyClientBehavior(description, proxy); } public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch) { IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description); innerBehavior.ApplyDispatchBehavior(description, dispatch); } public void Validate(OperationDescription description) { } } class ReferencePreservingDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior { public ReferencePreservingDataContractSerializerOperationBehavior(OperationDescription operationDescription) : base(operationDescription) { } public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes, 0x7FFF, //maxItemsInObjectGraph false, //ignoreExtensionDataObject true, //preserveObjectReferences null //dataContractSurrogate ); } public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes, 0x7FFF, //maxItemsInObjectGraph false, //ignoreExtensionDataObject true, //preserveObjectReferences null //dataContractSurrogate ); } }
What is it!
Any method will work just fine - choose the one that works for you.