在第4篇中,咱们了解了发送/接收SOAP头,从本篇开头,我们不妨更深入地去探求一下有关WCF中的消息到底是啥玩意儿。WCF庞大而复杂,而从 MSDN文档中,你会看到许多很专业很抽象的东西,你不禁会问,文档中所说的,是不是都有用的呢?实用的理论还是有的,不过有些要点确实太抽象了,抽象到 有时候我也不知道用来干吗?

不过,数据协定应该算比较有用的东西,至少在你写WCF服务时还是会经常用到。

我们先不管数据协定是什么,就从一个例子入手吧。

1、以管理员身份运行VS,注意,要以管理员身份运行,不然等会儿可能启动不了服务器端。

2、我们这个例子(解决方案)包含两个项目——服务器端和客户端。

3、为了简单起键,我都使用控制台应用程序。

服务器端的实现:

首先定义一个简单的类Employee,现在我们只用普通方式来定义该类,也不添加数据协定特性,在服务器方法协定中把一个Employee实例返回到客户端。我们测一测在不声明数据协定的情况下能不能成功调用。

    public class Employee{public string Name { get; set; }public int Age { get; set; }}

以下是服务协定的实现:

    [ServiceContract]public interface IService{[OperationContract]Employee GetAEmployee();}

    public class MyService : IService{public Employee GetAEmployee(){return new Employee { Name = "小朋友", Age = 32 };}}

      class Program{static void Main(string[] args){Uri url = new Uri("http://localhost:1233/services");using (ServiceHost host = new ServiceHost(typeof(MyService), url)){// 绑定的BindongNetHttpBinding binding = new NetHttpBinding();var ep = host.AddDefaultEndpoints();ServiceMetadataBehavior mb = new ServiceMetadataBehavior();mb.HttpGetEnabled = true;mb.HttpGetBinding = binding;host.Description.Behaviors.Add(mb);try{host.Open();//打开服务Console.WriteLine("服务已启动。");}catch (Exception ex){Console.WriteLine(ex.Message);}Console.ReadKey();}}}

现在先运行一下,确定服务器可以正常启动即可。

接下来看看客户端,为了添加服务引用,请到服务器端调试目录(bin\debug)下,以管理身份动行服务器端,然后回到VS,往客户端项目添加服务器端引用。

添加成功后,编写客户端实现代码:

        static void Main(string[] args){ws.ServiceClient cl = new ws.ServiceClient();Console.WriteLine("正在调用服务方法……");var em = cl.GetAEmployee();Console.WriteLine("员工信息\n姓名:{0}\n年龄:{1}", em.Name, em.Age);Console.ReadKey();}

确保服务器端还在运行,然后调试运行客户端,如果通信成功,你会看到以下结果。

这个例子只是说明了,如果在协定方法上出现非基元类型,在客户端引用时,可以生成对应类,至少表明,可被序列化的类型是没有问题的。非基元类型是啥,就是CLR的最简单的类型,如int, bool, float, long..................据说DateTime也是。

我们看看客户端生成的类是啥样的。

与服务器端不同,类实现了两个接口:IExtensibleDataObject, INotifyPropertyChanged。如果你觉得不好理解,那可以不管它,因为这不影响我们的实际应用。

下面我们再把刚才的代码修改一下,在服务器端,我们重新定义一下Employee类,这回我们使用数据协定来标注。

    [DataContract]public class Employee{[DataMember]public string Name { get; set; }[DataMember]public int Age { get; set; }public string City { get; set; }}

接着重新运行一下,注意,客户端的服务引用也要更新。接着再运行一下客户端,从表面上看,似乎和前面没有使用数据协定时没有区别。不过,你还是仔细看看 Employee的定义,发现了没有?在Employee类的定义中有一个City属性,但是,在客户端更新服务后,在客户生成的代码中还是没有City 属性,换句话说,只是应用了DataMember特性的成员才算是数据成员。

现在,我们再把Employee类修改一下,为City属性也加上DataMember特性。

    [DataContract]public class Employee{[DataMember]public string Name { get; set; }[DataMember]public int Age { get; set; }[DataMember]public string City { get; set; }}

然后更新一下客户端的服务引用,看看这回生成的代理代码中还有没有City属性?

这回在客户端生成的代码中,就见到了City属性了。所以,我们现在明白了一件事,使用数据协定可以灵活控制哪些成员应该被客户端识别。

其实,数据成员也可以用于字段,哪怕是私有字段,看看下面的修改。

    [DataContract]public class Employee{[DataMember]public string Name { get; set; }[DataMember]public int Age { get; set; }[DataMember]public string City { get; set; }[DataMember]private string _address;}

现在Employee类多了一个私有字段作为数据成员,看看客户端生成的代码有何变化。

我们也看到了这个私有字段,不过,就是因为它是私人财产,你无法直接拿来用。好,现在我们把Employee类再修改一下。

    public class Employee{[DataMember]public string Name{get { return this._name; }set { this._name = value; }}[DataMember]public int Age{get { return this._age; }set { this._age = value; }}[DataMember]public string City{get { return this._city; }set { this._city = value; }}// 字段列表[DataMember]private string _name;[DataMember]private int _age;[DataMember]private string _city;}

这一次,客户端又会生成什么代码呢?

我们发现,不管在服务器端我们把数据成员定义为公共属性还是私有字段,到了客户端都全变成公共属性了。为了验证这一点,我们把Employee类再次进行修改,把所有的成员都改为私有字段。

    [DataContract]public class Employee{[DataMember]private string Name;[DataMember]private int Age;[DataMember]private string City;}

由于私有字段不能被外部访问,因此,服务代码也要修改。

    public class MyService : IService{public Employee GetAEmployee(){return new Employee();}}

这样一来,我们看看客户端又会生成啥样子的代码。

很显然,到客户端,所有数据成员都成了公共属性了。这什么会这样呢?其实数据协定是通过XML来传输的,你想一想XML序列化的特点就找到些启发了,XML序列化和反序列化只针对公共成员,所以,如果希望让私有的数据成员也能进行序列化,能做的事情就是把数据成员都变成公共成员。这一点MSDN上也有相关说明。

数据协定还有一个很好的用处,那就是隐藏身份,比如我们把Employee作以下修改:

    public class MyService : IService{public Employee GetAEmployee(){return new Employee() { Name = "小胡", Age = 32, City = "南京" };}}

    [DataContract(Name = "Worker")]public class Employee{[DataMember(Name = "Worker_Name")]public string Name { get; set; }[DataMember(Name = "Worker_Age")]public int Age { get; set; }[DataMember(Name = "Worker_City")]public string City { get; set; }}

这一次,客户端生成的类,类名、属性名全变了,虽然变成了另一个类,但里面的数据还是从服务器端的Employee类传递的。

所以说,数据协定也有隐藏真实身份的作用。

转载于:https://www.cnblogs.com/GoogleGetZ/p/5752306.html

传说中的WCF(5):数据协定(a)相关推荐

  1. 传说中的WCF(6):数据协定(b)

    我们继续,上一回我们了解了数据协定的一部分内容,今天我们接着来做实验.好的,实验之前先说一句:实验有风险,写代码须谨慎. 实验开始!现在,我们定义两个带数据协定的类--Student和AddrInfo ...

  2. 传说中的WCF:消息拦截与篡改

    我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...

  3. 重温WCF之数据契约和序列化(四)

    一.数据契约 1.使用数据协定可以灵活控制哪些成员应该被客户端识别. [DataContract]public class Employee{[DataMember]public string Nam ...

  4. DataContract 添加到 DataContractSet,因为已经存在数据协定名称也为命名空间

    因为我使用了泛型数据合同,使用的名字又是同一个,所以就会报个错误, System.InvalidOperationException: 在调用 WSDL 导出扩展过程中引发异常: System.Ser ...

  5. WF是什么系列之[基于WF与WCF构建数据逻辑层]

    WF是什么,许多对NET技术有了解的人能说出一点,但又说不清楚 不论你认为WF是什么,但不要与Jbpm ,Shark ,Biztalk,SharePoint 这些产品做比效,这些产品有共同的特点就是面 ...

  6. ExtJs学习笔记(21)-使用XTemplate结合WCF显示数据

    个人认为,XTemplate是ExtJs中最灵活的用来显示数据的组件,有点类似aspx中的Repeater控件,显示数据的模板完全可以由用户以html方式来定制. 先给一个官方的静态示例(稍微改了下) ...

  7. 【转】解决WCF大数据量传输 ,System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接...

    开发中所用的数据需要通过WCF进行数据传输,结果就遇到了WCF大量传输问题 也就是提示System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接 网上解决 ...

  8. WCF 之 数据契约

    前面几篇讲的都只能传递string类型的简单参数,数据契约就是用来解决如传递一个带有多个属性的Class类型的对象的. WCF推荐使用数据契约的方式实现数据的序列化.这部分的内容很好理解但是很重要,先 ...

  9. 关于silverlight+MVVM+WCF保存数据出错的问题

    最近在用silverlight开发一个项目,由于接触比较浅,做起来真是一个头两个大.一个简单的数据更新操作费了好多天,哎 期间的点点滴滴打算记录起来,就当是给自己的纪念吧,哈哈~. 单表更新:表结构如 ...

最新文章

  1. 兄弟!kafka的重试机制,你可能用错了~
  2. 一首凉凉送给这些学校硕博生!本学期不必返校!这些高校已经发布通知了
  3. LeNet训练MNIST
  4. KVM virtio_net之NAPI机制(十七)
  5. 栈 - 关于出栈序列,判断合法的出栈序列
  6. 中国非动物胶市场来产销需求及发展潜力研究报告2022版
  7. fck2.6.3配置
  8. android studio的 gradle 依赖同步错误解决方法
  9. 关于如何在Listener中注入service和ServletContextListener源码分析
  10. Struts2之类型转换器
  11. NP、OSPF监测调试
  12. java字体除了宋体,为什么许多中文网站的主要字体仍然采用宋体而不是微软雅黑?...
  13. 采样准则(时间采样与采样频率)的选取
  14. 解决活动桌面问题获得
  15. 2022-2027年中国皮肤病药物市场竞争态势及行业投资前景预测报告
  16. maya! board_3D角色模型很难做?Maya、Zbrush人头建模终极秘笈
  17. 英语水平测试项目----总结遇到的问题
  18. jekins基本配置
  19. C++智能指针shared_ptr的使用方法
  20. js对手机号进行脱敏处理

热门文章

  1. 怎么监控一个接口的传输数据_监控安装超详细教学教程,学会又多一门技能
  2. 网络营销——浅析网站改版之后对网站展开新的网络营销有哪些影响?
  3. 网站优化之网站文章更新需注意哪些问题?
  4. SEO优化中影响网站关键词排名的因素有哪些?
  5. 计算机网络数据容量100M,华工网络教育计算机网络作业及答案
  6. android悬浮窗按钮在哪,android——悬浮窗控件Toast
  7. vrp车辆路径问题 php,蚁群算法在车辆路径问题(VRP)中的应用.ppt
  8. 动态域名作为dga的做法
  9. flask 返回html json 并让ios 安卓接收
  10. JLOI2015 战争调度