数据协定最重要的当然就是DataContract和DataMember。这两个特性能应用到类、结构和枚举。这个两个特性跟服务契约的特点是一样的,只有被DataContract标记的类和类中被标记DataMember的属性、字段和事件才能被wcf的序列化引擎进行序列化和反序列化。
[DataContract] public class UserInfoModel { private int age; [DataMember] public int Age { get { return age; } set { age = value; } } private string name; [DataMember] public string Name { get { return name; } set { name = value; } } [DataMember] private Gender gender; public Gender Gender { get { return gender; } set { gender = value; } } } [DataContract] public enum Gender { [EnumMember] Men = 1, [EnumMember] women = 2 }
这是我的一个简单的数据契约,在定义枚举的时候要用EnumMember,不然你会看到你的枚举会变成string类型。泛型类的处理方式与非泛型类的相同。
数据协定的命名空间NameSpace采用统一资源标识符(URI)的形式进行设置,数据协定的默认值与类名相同,可以通过Name属性重写,数据成员的Name属性的用法和数据协定的Name相同。
等效性:要使数据协定等效则命名空间和名称必须相同且数据成员的名称也必须相同,不然会引发异常。
数据成员的Order属性也会影响数据协定的等效性,数据成员的排序规则:基类成员->没有order属性的成员->order(如果order值相同则以成员的字母排序)。
DataMember的IsRequired标识该数据成员是否为必须,值为Bool型。
服务端:
[DataContract(Namespace = "www.wa3ha.com", Name = "People")] public class UserInfoModel { private int age; [DataMember(Order=1)] public int Age { get { return age; } set { age = value; } } private string name; [DataMember(IsRequired=true)] public string Name { get { return name; } set { name = value; } } private Gender gender; [DataMember] public Gender Gender { get { return gender; } set { gender = value; } } private string nativePlace; [DataMember(Order=2)] public string NativePlace { get { return nativePlace; } set { nativePlace = value; } } } [DataContract] public enum Gender { [EnumMember] Men = 1, [EnumMember] women = 2 }
客户端:
Svcutil.exe生成的代理:
还有一个比较重要的是KnownType,这个推荐看http://www.cnblogs.com/danielWise/archive/2011/06/23/2088464.html园子里的这位的博客!
数据协定版本重大变更:更改协定的Name或者NameSpace;更改DataMember的Order;将DataMember的IsRequired从false变更为true或删除IsRequired为true的成员;重命名数据成员;更改数据成员的数据协定。这些细想一下还是能理解为什么的,就不多说了。
将具有额外字段的类型反序列化为具有缺失字段的类型时,将忽略该字段,反之,额外字段将保留其默认值,0或者null。