- 将 DataMember attribute 应用于属性,而不是相应的字段。
- 不要使用类型继承来更改数据协定,而是修改现有的类型或者创建一个全新的类型。
- 不要添加或删除版本之间的枚举成员。
- 不要更改数据协定或者版本间数据成员的名称、命名空间。
- 不要更改版本间数据成员的顺序。
- 在更高版本中新加的数据成员上将 IsRequired property 设置为 false.
- 不要再更高版本中删除数据成员,即使已经不再需要它们。
- 使数据协定实现 IExtensibleDataObject 接口,从而可以通过扩展类型来支持未来的兼容性。
- 仅仅在公共成员上使用 DataMember attribute. 对于部分信任环境来说私有数据成员的序列化是不被支持的。
- 对部分信任的调用者来说,不用企图通过构造函数的可见性、链接要求、安全操作或者构造函数中的验证检查来使得一个 DataContract 标识的类型安全。在初始化一个对象时 DataContractSerializer 不会调用构造函数。
PS: 附原文
I was asked to share a list of best practices I wrote for data contracts and data members so here it is:
- Do apply the DataMember attribute only to properties rather than the corresponding fields.
- Do not use type inheritance to version a data contract. Either modify the existing type or create an entirely new type.
- Do not add or remove enumeration members between versions.
- Do not change the name or namespace of a data contract or data members between versions.
- Do not change the order of data members between versions.
- Do set the IsRequired property to false on data members added in later versions.
- Do not remove data members in later versions even if they are marked as not required.
- Do support IExtensibleDataObject on data contracts to support future compatibility with extended types.
- Do apply the DataMember attribute only to public members. Serialization of private data members is not supported for partial trust environments.
- Do not rely on constructor visibility, constructor link demands, constructor security actions, or validation checks in the constructor to make a DataContract type safe for partially trusted callers. DataContractSerializer does not invoke the constructor when initializing an object.