• WCF服务编程——数据契约快速入门


    WCF序列化流程

    操作调用期间的序列化与反序列化

    序列化

    默认用户自定义类型(类和结构)并不支持序列化,因为.NET无法判断对象状态是否需要反射到流。 用户自定义类的实例支持序列化 需要添加[Serialazable]。若要允许可序列化类型包含非序列化的成员变量可使用[NonSerializad]

    .Net格式器

    BinaryFormatter 序列化为二进制格式
    SoapFormatter 使用.NET 特定的SOAP XMl格式
    两者格式器都实现IFormatter接口

    两种格式器都要将类型的程序集及版本控制器信息持久化到流中,以保证序列化的对象能够被反序列化为正确的类型。

    WCF格式器

    使用[DataContract]进行标记类,使用[DataMember]标记成员
    DataContractSerializer格式器继承XmlObjectSerializer。
    在未曾标记DataContract特性,WCF就会自动推断,认为DataContract特性被应用到该类型上,且它的所有仅有成员(字段或属性)均被应用了DataMember特性。
    组合数据契约:定义数据契约,对那些本身就是数据契约的成员也可以使用DataMember特性。-数据契约具有递归性质
    数据契约事件 serializing发生成在序列化之前,serialized事件发生在序列化后,desrializing发生在反序列化之前,desreialized发生在反序列化之后

    每个序列化事件处理方法都必须遵循如下的方法签名 void <Method Name>(StreamingContext context)
    序列化 反序列化
    WCF在反序列化前必须创建一个对象,但是,WCF不会调用数据契约类的默认构造函数。

    数据契约层级

    WCF要求类层级的每一级数据契约都必须标记DataContract特性,该特性不可继承。WCF可以在类层级混合使用Serializable和DataContract特性
    WCF不能接收子类型数据,只能使用[KnownType(typeof(subclass))] 或[ServiceKnownType(typeof(SubClass))]

    配置文件方法

     <add type="Contact,MyClassLibrary">
       <knownType type="Customer,MyOtherClassLibrary"/>
     </add>
    

    使用配置文件主要解决的问题是:当添加一个新的子类时必须修改代码、重新编译和重新部署。

    序列化顺序

    在类型内部,默认的序列化顺序是按照字母的排序的,至于整个类层级的顺序,则是自上而下的。在序列化顺序不匹配的情况下,成员则以它们的值进行初始化。 自定义顺序可以使用[DataMember]的Order属性值进行调整,该属性的默认值为-1,也就是它默认WCF顺序

    成员的Order属性设置了相同的值,WCF会按照成员的字母顺序排序

    版本控制

    • 新增成员;
      任何一端添加新的成员,然后将新的契约发送到旧的客户端或服务。在反序列化这样的数据契约类型时,DataContractSerializer会忽略新增成员。
    • 缺失成员;
      客户端是针对旧的数据契约定义编写的,而与之交互的服务则是根据定义了新成员的契约定义编写的。当接收端的DataContractSerializer在消息中无法找到所需信息去反序列化的这些成员时,会根据成员的值进行反序列化。也就是说,将引用类型设置为null,将值类型设置为0。
    • 双向传递,即新的数据契约与旧版本的数据契约之间相互传递,它同时需要向后与向前的兼容性。
      版本的双向传递可能会影响整体的交互

      枚举

      枚举类型总是支持序列化的。不必应用DataContract特性,如果要将确定的枚举值排除于数据契约之外,就需要在枚举类型标记DataContract特性,并在枚举值明确标记为[EnumMember]特性,没有标记EnumMember毛发的枚举值不属于该枚举的数据契约。同时可以使用该特性的Value属性对枚举值设置别名。

      泛型

      不能定义包含了泛型类型参数的数据契约。便可以在数据契约中使用限定的泛型数据,只要在服务契约中指定了类型参数。
      数据契约被重命名的格式为:<原有名>Of<类型参数><散列值>
      同时也可以使用[DataContract(Name=”ClassNameOf{0}{1}”)]表示。标识符中的数字就是类型参数的序数,可以用{#}表示为散列值

      集合

      在使用集合接口IEnumberable,IList和ICollection,它他的传输型表示形式都使用了数组

      如果契约中的集合为具体集合类型,而且属于可序列化集合(标记为Serializable特性而不是DataContract特性),那么,只要提供的集合包含Add()方法,WCF就能够自动地将集合规范为数组类型。

      CollectionDataContract特性:该特性会检验Add()方法及检查IEumerable或IEnumerable接口是否存在。如果不存在,就会导致InvlidDataContractException异常。注:DataContract不能和CollectionDataContract一起使用

  • 相关阅读:
    SqlServer 本地连接打不开
    Ftp服务器搭建方法
    SQL分页查询
    sql 多表更新
    SQL 循环截取指定位置字符串
    创建在“system.net/defaultProxy”配置节中指定的 Web 代理时出错。
    python入门学习的第一天
    操作系统第二章总结/
    操作系统第一章总结/
    终端执行for循环
  • 原文地址:https://www.cnblogs.com/chenmoit/p/4362654.html
Copyright © 2020-2023  润新知