zoukankan      html  css  js  c++  java
  • WCF学习(五)数据契约之已知类型

    准备技术:

         1.C#基础知识

         2.了解WCF基础知识

         在正常的c#开发中我们是允许用子类去替换基类的,这也是所谓的替换原则。但是我们在WCF中确不能用数据契约的子类来替换父类的,因为这中间存在一个序列化的问题。举个例子:

         我们有数据契约:

              [DataContract]

              class Employee{...}

         服务契约中:

              [ServiceContract]

              interface IEmployeeManager

              {

                   [OperationContract]

                   void AddEmployee(Employee employee);

              }

         然后我们在客户端的代理中就算有类:Intern继承于

              [DataContract]

              class Intern:Employee{...}

         然后再客户端调用时:

              proxy.AddEmployee(new Intern())是会出错的。因为在服务器端无法识别Intern对象,因为他无法去反序列化Intern成Employee对象(WCF序列化)。

         

         

         WCF提供给我们了一个解决的办法就是使用KnownTypeAttribute特性,在基类上标识对应的子类就可以了。KnownTypeAttribute特性可以使用在Struct跟Class上。示例:

              [DataContract]

              [KnownType(typeof(Customer))]

              class Employee{...}

              

              [DataContract]

              class Intern:Employee{...}

    这样我们就在所有的契约跟操作上,能跨越所有的服务和终结点,允许服务接受子类。但是这样会遇到一个问题,我们不能去特定的指定某一个服务操作,所以KnownType的缺陷就是范围过于广泛。WCF提供了另外一个Attribute--ServiceKnownType.

    ServiceKnownType 特性

         KnownType只能应用在数据契约的基类上,而ServiceKnownType可以在Interface、Method、Class上标识。看一个示例Employee.cs:

    Code

    在数据契约中我们并没有去指定KnownType,我们在服务契约的操作上去标识ServiceKnownType特性,EmployeeManage.cs:

    Code

    在客户端我们调用:

    Code

    运行后: 

         ServiceKnownType特性也可以表示在数据契约的类上,那么就会应用到整个数据契约中操作上,如:

              [ServiceContract]

              [ServiceDataContract(typeof(HenllyeeDataContract.Intern))]

              public interface IEmployeeManage{...}

         那么IEmployeeManage服务契约跟其所有的操作都可以接受Intern这个子类.

    已知类型与接口

         数据契约DataContract只能标识在class 或者struct上,但是数据契约的基类可以是接口,但是我们在服务契约的时候要去用ServiceKnownType特性去指定确切的数据类型。如:

         interface IEmployee{...}

         [DataContract]

         class Intern:IEmployee{...}

    服务契约中:

         [ServiceContract]

         [ServiceKnownType(typeof(Intern))]

         interface IEmployeeManage

         {

              [OperationContract]

              void AdddEmployee(IEmployee employee);

         }

    要注意的一点就是我们不能把KnownType特性应用到基接口上,因为客服端导出的元数据是不能包含接口本身的。

    [代码下载]

    作者:Henllyee Cui
    出处: http://henllyee.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
  • 相关阅读:
    SpreadJS 复制行
    RookeyFrame 模块 线上创建的模块 迁移到 线下来
    RookeyFrame 附件 上传附件
    RookeyFrame 字典 新增和绑定
    RookeyFrame Bug 表单管理 -> 查看表单 ->编辑字段页面 JS报错
    Catalan数
    美元汇率
    5倍经验日
    二分查找的边界问题
    线段覆盖5
  • 原文地址:https://www.cnblogs.com/Henllyee/p/1276995.html
Copyright © 2011-2022 走看看