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类型的就可以保持对象的引用结构了。
浙公网安备 33010602011771号