2、数据契约。

1)、数据契约的本质:数据契约的本质就是定义了,数据在进行信息交换的数据结构,数据结构相同的客户端和服务端才能正常的进行消息交换。

2)、DataContractAttribute与DataMemberAttribute:

  a、DataContractAttribute特性,是一个sealed类型的,契约不能被继承(如果父子类都是数据契约,都必须加DataContract特性),所有应用这个特性的类型也不可以被继承,Allowmultiple属性为false,表示一个数据类型上只能应用一个DataContract特性。

  b、DataMemberAttribute特性,一个数据成员上,只有应用了DataMember特性,才可以成为数据契约的成员,不管这个成员访问权限是私有的还是公有的。

3)、DataContractSerializer:

  DataContractSerialize继承自System.Runtime.Serializer.XmlObjectSerializer类,XmlObjectSerializer是个抽象类,里面提供了ReadObject和WriteObject函数,ReadObject读取xml的内容并将其反序列化成相应的对象,WriteObject函数,则将可序列化对象序列化成xml,并通过Stream、XmlWrite和XmlDictionaryWrite的方式进行输出。

  DataContractSerializer核心成员如下:

  public sealed class DataContractSerializer:XmlObjectSerializer

  {

    public DataContractSerializer(Type type);

    public override object ReadObject(XmlReader reader);

    public override object ReadObject(XmlDictionaryReader reader,bool verifyObjectName);

    public override object ReadObject(XmlReader reader,bool verrifyObjectName);

 

    public override void WriteObject(XmlWriter writer,object graph);

    public IDataContractSurrogate DataContractSurrogate{get;}//返回一个企业代理类的对象,用于干预DataContractSerializer的序列化、反序列化,以及契约的导入导出行为。

    public bool IgnoreExtensionDataObject{get;}//扩展数据对象,解决双方数据契约不一致的情况下数据传送-回传过程中造成的数据丢失。

    public ReadOnlyCollect<Type> KnownTypes{get;}//和XmlSerialize一样,就是在进行序列化之前明确对象中涉及的所有真实类型(有继承关系的)

    public int MaxItemsInObjectGraph{get;}//设置进行序列化和反序列化允许的最大对象数,默认是65536.

    public bool PreserveObjectReferences{get;}//表示如果数据对象的多个属性或字段引用相同的对象,在序列化的时候是否需要在xml中保持一样的引用结构。

  }

1)、DataContractSerializer的序列化规则:

  • XML的根节点名称为数据契约类型的名称,默认的命名空间是数据契约类型的命名空间。
  • 只有显式地应用了DataMember特性的字段或属性才能作为数据成员参与序列化。
  • 所有数据成员均以Xml元素的形式被序列化。
  • 序列化数据成员在Xml中次序,父类数据成员在前,子类数据在后,同一个类型的数据成员按字母排序。

2)、如何限定序列化对象的数量:

  介绍这个之前,介绍一种黑客攻击行为——拒绝服务,黑客通过生成大容量的数据频繁的对服务发送请求,最终导致服务器不堪重负而崩溃。

  DataContractSerializer中具有一个只读的MaxItemsObjectGraph属性,表示允许被序列化或反序列化对象的数据上限,这个属性DataContractSerializer定义了三个构造函数,来初始化这个属性值,举个例子:

  public static void Serializer<T> (T instance,string fileName,int maxItemsInObjectGraph)

  {

    DataContractSerializer serializer = new DataContractSerilizer(typeof(T),null,maxItemsInObjectGraph,false,false,null);

    using(XmlWrite writer=new XmlTextWriter(fileName,Encoding.UTF8))

    {

      serializer.WriteObject(writer,instance);

    }

    Process.Start(fileName);

  }

  maxItemsInObjectGraph这个值计算规则:对象本身算一个,对象里每个成员都算一个,比如说List<Order>集合里,包含10个Order对象,每个Order对象中有5个属性,那么计算的结果就是10*5+1=51.

WCF中如何设置MaxItemsInObjectGraph 属性呢,有两个方式,一种是在服务上添加ServiceBehavior特性,设置这个特性里的MaxItemsInObjectGraph值,另外一种方式就是通过配置的方式:

  <behavior name ="">

    <dataContractSerializer maxItemsInObjectGraph="51"/>

  </behavior>

3)、如何保持对象现有的引用结构:

  前面讲过,DataContractSerializer里有一个PreseverObjectReferences属性,代表着是否保持对象的引用结构,同样也在DataContractSerializer构造函数中来初始化这个值,在WCF中我们可以在数据契约中添加(IsReference = true)的方式,来保持一个对象的引用结构。

  如:[DataContract(IsReference = true)]

    public class Address

    {....}

  这样数据成员类型是Address类型的就可以保持对象的引用结构了。

 

posted on 2013-07-15 21:59  Kelly_HanShuai  阅读(129)  评论(0)    收藏  举报