I have an existing set of classes that use the [Serializable]
attribute. I need to expose them in a WC开发者_开发问答F service and so I need them to have the [DataContract]
attribute. It works with just Serializable but then the properties get funny names like ...k__BackingField.
These classes are also used elsewhere and I'm wondering whether I risk breaking anything by replacing the attribute. Also, it is possible and is it a good idea to have them both?
Thanks.
When you just specify a DataContractAttribute but do not specifically attribute the members that you want included, the default behavior is to serialize all fields of the class, including private ones. So the names you are getting are because you are using automatically implemented properties, I assume.
So in other words, change the class definition to resemble the following. Note the DataMember attributes on the properties that I want serialized.
[DataContract]
public class MyClass {
[DataMember]
public string SomeString {
get;
set;
}
[DataMember]
public int SomeInt {
get;
set;
}
public string DontSerializeThis {
get;
set;
}
}
This will cause the DataContractSerializer to serialize the properties and not their compiler-generated backing fields. However, it does require that the properties be read/write public properties because it's going to go through these property accessors to get and set the serialized data.
The other option is to change your automatically implemented properties to "normal" properties which means adding your own backing fields. Then you can either leave all the DataMember attributes off which means they'll all be serialized, or you can add the DataMember attributes to the new fields you created which lets you rename them in the serialized output if you want.
Finally, to your point about whether it's a good idea to make a class serializable in both systems, not really. If you want the class to participate in classic serialization using something like BinaryFormatter or XmlSerializer, then you should just target that scenario since the DataContractSerializer can already serialize these classes.
If your goal is fast, efficient, .NET 3+ to .NET 3+ (or Silverlight) communication, DataContract is the way to go. If your goal is interoperability and/or control over the XML represenation, stick with the XML serialization attributes.
I think this code excerpt from Josh Einstein's answer:
public string DontSerializeThis {
get;
set;
}
will result in a property which backing field is serialized, because of the default behaviour mentioned in the same answer. It should be
[IgnoreDataMember]
public string DontSerializeThis {
get;
set;
}
For reference, see: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ignoredatamemberattribute.aspx
精彩评论