前面几篇讲的都只能传递string类型的简单参数,数据契约就是用来解决如传递一个带有多个属性的Class类型的对象的。

  WCF推荐使用数据契约的方式实现数据的序列化。这部分的内容很好理解但是很重要,先看[DataContract]和[DataMember]这两个就是数据契约的标记,他们在System.Runtime.Serialization命名空间下。

  1、[DataContract]:它用来实现Schema与CLR类型之间的转换。总是要提供命名空间,Web Service的规范要求使用“Schemas”前缀来表示服务目标的命名空间。

  2、[DataMember]:明确成员是否参与序列化;应用与域或属性;可以指定排列顺序,缺省按照字母表顺序排列;能够显示提供Name, IsRequired。

  注:对于复杂类型使用DataContractSerializer是一种较好的方法。下面用一个Demo来更好的说明:

  工程结构如下:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;namespace ContentTypes
{[DataContract(Name = "LinkItem_Contract", Namespace = "http://www.cnblogs.com/Charlesliu")]public class LinkItem{private long m_id;private string m_title;private string m_description;private DateTime m_dateStart;private DateTime m_dateEnd;private string m_url;[DataMember(Name = "Id_Contract", IsRequired = false, Order = 0)]public long Id{get { return m_id; }set { m_id = value; }}[DataMember(Name = "Title_Contract", IsRequired = true, Order = 1)]public string Title{get { return m_title; }set { m_title = value; }}[DataMember(Name = "Description_Contract", IsRequired = true, Order = 2)]public string Description{get { return m_description; }set { m_description = value; }}[DataMember(Name = "DateStart_Contract", IsRequired = true, Order = 3)]public DateTime DateStart{get { return m_dateStart; }set { m_dateStart = value; }}[DataMember(Name = "DateEnd_Contract", IsRequired = false, Order = 4)]public DateTime DateEnd{get { return m_dateEnd; }set { m_dateEnd = value; }}[DataMember(Name = "Url_Contract", IsRequired = false, Order = 5)]public string Url{get { return m_url; }set { m_url = value; }}}
}

  对上面的代码说明一下,[DataContract]的Name也是改变Client看到的名称,namespace和以前一样。[DataMember]推荐使用在属性上,Name的作用也是改变客户端看到的数据类的名字; IsRequired的作用是,当服务段添加了一个新的DataMember但是客户端没有更新服务的引用时,如果IsRequired=true,就会报错,原应是true代表这个DataMember一定要序列化才能正常通信,由于此时客户端不知道这个新DataMember的存在没有序列化它,所以报错了;IsRequired=false,可以正常使用。Order可以指定排列顺序,缺省按照字母表顺序排列。通过这两个标记定义的对象就可以在服务端和客户端之间传递了,WCF会自动实现数据的序列化等操作。

  再看一下Service代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ContentTypes;namespace WcfServiceLibraryDemo
{[ServiceContract(Name = "GigManagerServiceContract", Namespace = "http://www.cnblogs.com/Charlesliu", SessionMode = SessionMode.Required)]public interface IGigManagerService{[OperationContract(Name = "SaveGig", Action = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/SaveGig",       ReplyAction = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/SaveGigResponse")]void SaveGig(LinkItem item);[OperationContract(Name = "GetGig", Action = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/GetGig",       ReplyAction = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/GetGigResponse")]LinkItem GetGig();}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ContentTypes;namespace WcfServiceLibraryDemo
{[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]public class GigManagerService : IGigManagerService{private LinkItem m_linkItem;#region IGigManager Memberspublic void SaveGig(LinkItem item){m_linkItem = item;}public LinkItem GetGig(){return m_linkItem;}#endregion}
}

  这里引出了一个关键的会话设置,[ServiceContract(SessionMode=SessionMode.Required)] 应用在服务的接口上。
  SessionMode:指客户端代理与服务器之间的会话模式,同样也有三种类型:Allowed-允许会话、NotAllowed-不允许会话、Required-要求会话(需要有支持会话的Binding支持,WsHttpBinding、NetTcpBinding等)。
  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]应用在服务的类上。
  InstanceContextMode:指服务端实现服务契约类的实例模式,有三种类型,分别为:

  [1] PerCall-每次服务操作调用创建一次,调用完后进行销毁;

  [2] PerSession-同一个会话期间创建一次,客户端代理第一次操作(IsInitiating = true)调用创建,调用代理的Close方法销毁或者调用IsTerminating服务操作销毁;

  [3] Single-服务只会创建一次,服务开始时创建,服务完成时销毁。

  [1] PerCall下的会话模式
  单调服务的一个最重要优势在于它能够节省资源,支持系统的可伸缩性。由于服务实例的生命周期只存在于一次调用期间,特别对于那些持有昂贵资源的服务实例而言,这种方式可以有效地提高系统性能。而且,销毁服务实例时,WCF不会断开与客户端(通过客户端的代理)的连接,这比创建实例与连接所消耗的资源要少得多。
  [2] PerSession下的会话模式
  PerSession从字面上就可以理解为,对于每一个客户端代理或者说是会话创建一个实例,代理第一次调用服务契约操作创建实例,当代理调用Close方法或者Terminating方法([OperationContract(IsTerminating = true)])结束会话并释放服务实例,同时服务实例可以被垃圾回收。
  [3] Single下的会话模式
  Single模式下的服务只创建一次,而且是在服务打开的时候,这个模式比较好理解。

  如果把上面的代码中的PreSession改为PreCall,那么GetGig方法就会失效了,m_linkItem保存不了Save提交的数据。

  最后看客户端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WinTest.MyServiceReference;namespace WinTest
{public partial class Form1 : Form{MyServiceReference.GigManagerServiceContractClient m_proxy = new WinTest.MyServiceReference.GigManagerServiceContractClient();public Form1(){InitializeComponent();}private void cmdSave_Click(object sender, EventArgs e){LinkItem_Contract item = new LinkItem_Contract();
item.Id_Contract = int.Parse(this.txtId.Text);item.Title_Contract = this.txtTitle.Text;item.Description_Contract = this.txtDescription.Text;item.DateStart_Contract = this.dtpStart.Value;item.DateEnd_Contract = this.dtpEnd.Value;item.Url_Contract = this.txtUrl.Text;m_proxy.SaveGig(item);}private void cmdGet_Click(object sender, EventArgs e){LinkItem_Contract item = m_proxy.GetGig();if (item != null){this.txtId.Text = item.Id_Contract.ToString();this.txtTitle.Text = item.Title_Contract;this.txtDescription.Text = item.Description_Contract;if (item.DateStart_Contract != DateTime.MinValue)this.dtpStart.Value = item.DateStart_Contract;if (item.DateEnd_Contract != DateTime.MinValue)this.dtpEnd.Value = item.DateEnd_Contract;this.txtUrl.Text = item.Url_Contract;}}}
}

转载于:https://www.cnblogs.com/xinaixia/p/5779832.html

WCF 之 数据契约相关推荐

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

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

  2. WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)

    [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]在.NET中,所有的集合都实现了IEnumerable接口,比如Arra ...

  3. WCF步步为营(五):数据契约

    . WCF只能传输序列化的类型,WCF 能自动序列化.net内置的之类型,但是如果需要传输自定义的类型,必须把自定义的类型标注DataContract DataContract标注这个类作为数据契约, ...

  4. WCF契约的简单介绍(服务契约 数据契约 消息契约)

    本篇博文只是简单说下WCF中的契约的种类.作用以及一些简单的代码示例.在WCF中契约分为服务契约.数据契约和消息契约.下面对这几种契约进行简单的介绍. 服务契约 服务契约描述了暴露给外部的类型(接口或 ...

  5. WCF学习(五)数据契约之已知类型

    准备技术: 1.C#基础知识 2.了解WCF基础知识 在正常的c#开发中我们是允许用子类去替换基类的,这也是所谓的替换原则.但是我们在WCF中确不能用数据契约的子类来替换父类的,因为这中间存在一个序列 ...

  6. WCF简单教程(4) 数据契约

    第四篇:用数据契约传递自定义数据对象 之前的演示中,我们一直都是在用string类型做参数和返回值,实际项目中肯定会传递自定义的数据类型.与WebService不同,WCF想传递自定义数据,必须要将其 ...

  7. WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)

    在.NET Framework 2.0中,泛型第一次被引入.我们可以定义泛型接口.泛型类型.泛型委托和泛型方法.序列化依赖于真实具体的类型,而泛型则刻意模糊了具体类型概念.而集合代表一组对象的组合,集 ...

  8. WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用

    如果一个类型,不一定是数据契约,和给定的数据契约具有很大的差异,而我们要将该类型的对象序列化成基于数据契约对应的XML.反之,对于一段给定的基于数据契约的XML,要通过反序列化生成该类型的对象,我们该 ...

  9. WCF 第二章 契约

    在原子和金钱世界中,契约是两个或多个组织以一个已知的价格提供商品和服务的合同.在比特和服务的世界中,契约有类似的功能:它是两个或多个组织之间确定消息交换和消息条款及条件的合同. 契约是由服务终结点发送 ...

最新文章

  1. 【控制】《多智能体系统一致性与复杂网络同步控制》郭凌老师-第7章-Lurie 型动态网络的鲁棒 H 无穷簇同步
  2. Linux的pcel问题-bash: pecl: command not found
  3. Leetcode 583.两个字符串的删除操作
  4. linux 追加多行文件,linux多行文件信息追加
  5. Android 四大组件 —— 活动(使用Intent 实现活动的显示跳转)
  6. mysql中有sa_SA工作-mysql设计规范
  7. 阿里云96页报告详解《云上转型》(10个案例、10大趋势/完整版PPT)
  8. 不使用机器学习的机器视觉_使用机器学习为卡通着色
  9. 小程序获取运动步数php,微信小程序怎么获取php页面数据?
  10. python可视化编程实战代码_Python数据可视化编程实战——导入数据
  11. struts 2.3.8备忘
  12. 如何在word里插入矢量图
  13. ubuntu清理cache
  14. 百度地图缩放级别与比例尺的关系
  15. java list获取某个字段
  16. EOS测试链加入流程(代码版本与主网同步)
  17. Android Settings和SettingsProvider源码分析与修改,kotlin面试题和答案
  18. dovecot主要配置文件
  19. C++ Blah数集
  20. 焱融科技为国家重点实验室打造海量高性能存储

热门文章

  1. system.exception所有子类详解
  2. docker privileged作用_Docker 从入门到掉坑
  3. R语言ggplot2移除图例_读书笔记:R语言绘图—ggplot2
  4. 出现身份验证错误 要求的函数不受支持_学习使用Kotlin创建Android应用程序第3部分:身份验证登录...
  5. 倾心家教安卓案例开发代码_开发一个APP多少钱?
  6. 判断回文和查询最大公共字符串
  7. 关于el-form中的rules未生效问题的解决方法
  8. js 正则表达式判断价格
  9. html底部弹出选择,jQuery手机端底部弹出菜单列表特效代码
  10. vs code写ipynb怎么添加目录_用Django写招聘网站2——用户系统