[MSDN]WCF(6)数据协定

说明:本内容来自微软的webcast,讲师为徐长龙。为了用手机阅读方便点,抄录存为txt。

内容包括
- 1.数据协定概述
- 2.数据协定名称
- 3.数据协定等效性
- 4.数据协定已知类型
- 5.数据协定版本管理


1.数据协定概述
- 默认情况下,WCF使用称为数据协定序列化程序的序列化引擎对数据进行序列化和反序列化(与XML进行相互交换)
- 所有.NET Framework 基元类型(如整型和字符串型)以及某些被视为基元类型(如DateTime 和 XmlElement)无需做其他任何准备工作就可序列化并被视为拥有默认数据协定。
- 必须为所创建的新复杂类型定义数据协定以便可以进行序列化。
- 正常情况下可通过DataContractAttribute属性应用到该类型来完成任务。
- 可以将次属性应用到类、结构和枚举。
- 然后必须将DataMemberAttribute属性应用到数据协定类型的每个成员,以指示这些成员为数据成员,即应进行序列化。
- 数据协定是使用“选择性加入”编程模型设计的;未用DataMemberAttribute属性显式标记的任何内容均不序列化。
- 可以将 DataMemberAttribute 属性应用于字段、属性和事件。
- 成员访问级别(internal,private,protected或public)对数据协定无任何影响。
- 如果将 DataMemberAttribute 属性应用于静态成员,则将忽略该属性。
- 在序列化期间,为属性数据成员调用 property-get 代码来获取要序列化的属性的值。
- 在反序列化期间,首先创建一个未初始化的对象,而不在改类型上调用任何构造函数。然后反序列化所有数据成员。
- 在反序列化期间,为属性数据成员调用 property-set 代码,将属性设置为要反序列化的值。
- 对于将要生效的数据协定,它必须能序列化其所有数据成员。泛型类型的处理方式与非泛型类型完全相同。泛型参数无要求特殊。
- 无论用于泛型类型参数 (T) 的类型能否序列化,此类型都可序列化。因为它必须能序列化所有数据成员,所以下面的类型仅在泛型类型参数也可序列化时才可序列化。
[DataContract]
public class MyGenericType2<T>
{
  [DataMember]
  T theData;
}


2.数据协定名称
- 有时,客户端和服务不共享相同的类型。但要两端的数据协定是等同的,客户端和服务仍然可以相互传递数据
  - 完全限定的数据协定名称由命名空间和名称组成。
  - 数据成员只有名称,而没有命名空间。
  - 处理数据协定时,WCF基础结构对于命名空间以及数据协定和数据成员的名称区分大小写。
- 数据协定命名空间
  - 数据协定命名空间采用统一资源标示符(URI)的形式
  - 设置DataContractAttribute 的 Namespace 属性
- 数据协定名称
  - 给定类型的默认数据协定名称是该类型的名称
  - 若要重写默认值,请将DataContractAttribute 的 Name 属性设置为其他名称
- 数据成员名称
  - 给定字段或属性的默认数据成员名称是该字段或属性的名称。
  - 若要重写默认值,请将DataMemberAttribute 的 Name 属性设置为其他值


3.数据协定等效性
- 要使用数据协定等效性,其命名空间和名称必须相同。此外,某一端上的数据成员还必须在另一端上具有等效的数据成员。
- 要使数据成员等效,其名称必须相同。此外,它们还必须标示同一类型的数据,也就是说,其数据协定必须等效。
- 如果同一端(发送方或接收方)存在两种类型,而其数据协定又不等效(例如,它们的数据成员不同),则不应为它们指定相同的名称和命名空间。否则,可能会引发异常。
例如下面Customer与Person是等效的
[DataContract]
public class Customer
{
    [DataMember]
    public string fullName;
    [DataMember]
    public string telephoneNumber;
}

[DataContract(Name="Customer")]
public class Person
{
  [DataMember(Name="fullName")]
  private string nameOfPerson;
  private string address;
  [DataMember(Name="telephoneNumber")]
  private string phoneNumber;
}
- 数据成员顺序和数据协定等效性
  - 使用 DataMemberAttribute 类的 Order 属性可能会影响数据协定等效性。其成员必须以相同顺序出现,数据协定才能等效。默认顺序是按字母顺序。
- 数据排序的基本规则包括:
  - 如果数据协定类型是继承层次结构的一部分,则其基类型的数据成员始终排在第一位。
  - 排在下一位的是当前类型的数据成员(按字母顺序排列),这些成员未设置 DataMemberAttribute 属性(attribute) 的 Order 属性(property)的任何数据成员。这些成员首先按 Order 属性的(property)
  - 在下面是设置了 DataMemberAttribute 属性(attribute)的 Order 属性(property)的任何数据成员。这些成员首先按 Order 属性的值排序,如果多个成员具有特定的 Order 值,则按字母顺序排列。可以跳过 Order 值

4.数据协定已知类型
- 数据协定已知类型
  - 发送的数据协定源自预期的数据协定
  - 要传输的信息的声明类型是接口,而非类、结构或枚举
  - 要传输的信息的声明类型是 Object
  - 有些类型(包括.NET Framework类型)具有属于上述三种类别之一的成员。例如,Hashtable 使用 Object 在哈希表中存储实际对象
- KnownTypeAttribute
  - 通过首先检查传入消息选择为反序列化而实例化的类型,以确定消息内容遵循的数据协定。然后反序列化引擎尝试查找实现与消息内容兼容的数据协定的CLR类型。反序列化引擎在此过程中允许的候选类型集称为反序列化程序的“已知类型”集。
- 让反序列化引擎了解某个类型的一种方法是使用 KnownTyoeAttribute。
- 不能将属性应用于单个数据成员,只能将它应用于整个数据协定类型。
- 将属性应用于可能为类或结构的“外部类型”。在其最基本的用法中,应用属性会将类型指定为“已知类型”。只要反序列化外部类型的对象或通过其成员引用的任何对象,这就会导致已知类型成为已知类型集的一部分。
- 可以将多个 KnowTypeAttribute 属性应用于同一类型。

5.数据协定版本管理
- 重大更改与非重大更改
  - 对数据协定的更改可能是重大更改,也肯能是非重大更改。对数据协定进行非重大更改时,使用较早版本的应用程序和使用较新版本协定的应用程序可以互相通信。另一方面,如果进行重大更改,则会阻止单向或双向通信。
- 下面的更改始终是重大更改
  - 更改数据协定的 Name 或 Namespace 值。
  - 通过 DataMemberAttribute 的 Order 属性来更改数据成员的顺序。
  - 重命名数据成员
  - 更改数据成员的数据协定
- 添加或移除数据成员
  - 将具有类外字段的类型反序列化为具有缺失字段的类型时,将忽略额外的信息。
  - 具有缺失字段的类型反序列化为具有额外字段的类型时,额外字段将保留其默认值,通常为零活 null。
- 不需的数据成员
  - 通过将 DatamemberAttribute 的 IsRequired 属性设置为 true,可以将数据成员标记为必需的数据成员。如果反序列化时缺少必需的数据,则会引发异常,而不是将数据成员设置为其默认值。
  - 添加必需的数据成员是重大更改。
  - 移除在任何早期版本中标记为必需成员的数据成员也是重大更改。
  - 将 IsRequired 属性值从 true 更改为 false 不是重大更改;如果类型的任何早期版本都没有相应数据成员,将该属性值从 false 更改为 true 就可能是重大更改。

原文地址:https://www.cnblogs.com/htht66/p/2328851.html