WCF 之 数据契约
前面几篇讲的都只能传递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 = )]
public long Id
{
get { return m_id; }
set { m_id = value; }
} [DataMember(Name = "Title_Contract", IsRequired = true, Order = )]
public string Title
{
get { return m_title; }
set { m_title = value; }
} [DataMember(Name = "Description_Contract", IsRequired = true, Order = )]
public string Description
{
get { return m_description; }
set { m_description = value; }
} [DataMember(Name = "DateStart_Contract", IsRequired = true, Order = )]
public DateTime DateStart
{
get { return m_dateStart; }
set { m_dateStart = value; }
} [DataMember(Name = "DateEnd_Contract", IsRequired = false, Order = )]
public DateTime DateEnd
{
get { return m_dateEnd; }
set { m_dateEnd = value; }
} [DataMember(Name = "Url_Contract", IsRequired = false, Order = )]
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 Members public 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;
}
}
}
}
WCF 之 数据契约的更多相关文章
- 重温WCF之数据契约中使用枚举(转载)(十一)
转载地址:http://www.zhuli8.com/wcf/EnumMember.html 枚举类型的定义总是支持序列化的.当我们定义一个新的枚举时,不必应用DataContract特性,就可以在数 ...
- 重温WCF之数据契约和序列化(四)
一.数据契约 1.使用数据协定可以灵活控制哪些成员应该被客户端识别. [DataContract] public class Employee { [DataMember] public string ...
- WCF之数据契约
从抽象层面看,WCF能够托管CLR类型(接口和类)并将它们公开为服务,也能够以本地CLR接口和类的方式使用服务.然而,CLR类型却属于.NET的特定技术.由于面向服务的一个核心原则就是在跨越服务边界时 ...
- WCF中数据契约之已知类型的几种公开方式
WCF中传输的数据不想传统的面向对象编程,它只传递了一些对象的属性,但是自身并不知道自己属于什么对象,所以,他没有子类和父类的概念,因而也就没有Is-a的关系,所以在WCF中,如果想维持这种继承关系, ...
- WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer)
原文:WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济 ...
- 跟我一起学WCF(7)——WCF数据契约与序列化详解
一.引言 在前面博文介绍到,WCF的契约包括操作契约.数据契约.消息契约和错误契约,前面一篇博文已经结束了操作契约的介绍,接下来自然就是介绍数据契约了.所以本文要分享的内容就是数据契约. 二.数据契约 ...
- WCF分布式开发步步为赢(7):WCF数据契约与序列化
本节继续学习WCF分布式开发步步为赢(7):WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤.那么序列化是什么?为 ...
- WCF契约之---服务契约 、数据契约、 消息契约
本篇博文只是简单说下WCF中的契约的种类.作用以及一些简单的代码示例.在WCF中契约分为服务契约.数据契约和消息契约.下面对这几种契约进行简单的介绍. 服务契约 服务契约描述了暴露给外部的类型(接口或 ...
- WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用
原文:WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经> ...
随机推荐
- RxSwift 系列(七)
前言 本篇文章将要学习RxSwift中连接操作符.Connectable Observable在订阅时不发射事件消息,而是仅当调用它们的connect()方法时才发射消息,这样就可以等待所有我们想要的 ...
- Selenium之PhantomJS相关设置
设置PhantomJS请求头 默认情况下: from selenium import webdriver import time driver = webdriver.PhantomJS() driv ...
- 【BZOJ 3560】 3560: DZY Loves Math V (欧拉函数)
3560: DZY Loves Math V Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 241 Solved: 133 Description ...
- bzoj 1115: [POI2009]石子游戏Kam -- 博弈论
1115: [POI2009]石子游戏Kam Time Limit: 10 Sec Memory Limit: 162 MB Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前 ...
- web前端 -- onkeydown、onkeypress、onkeyup、onblur、onchange、oninput、onpropertychange的区别
FROM:http://www.cnblogs.com/svage/archive/2011/11/15/2249954.html onkeydown:按下任何键(字母.数字.系统.tab等)都能触发 ...
- 提示框框架KVNProgress介绍
gitHub上面有很多显示加载进度的框架,这里我们介绍一下KVNProgress框架,KVNProgress是一个可以完全定制的HUD(指示器),你可以设置加载进度的画面是否全屏,可以自己修改进度显示 ...
- Apache Hadoop 简介
什么是Apache Hadoop? 在Apache Hadoop的项目开发可靠,可扩展,分布式计算开源软件. Apache Hadoop的软件库是一个框架,允许分布式处理大型数据集在集群计算机使用简单 ...
- JavaScript的最大函数參数长度和最大栈深度检測
一般代码也许不会涉及最大參数长度和最大栈深度,但某些特殊场合,检測这两个參数还是有必要的.比如:用递归计算斐波那契数列的第n个值,不了解最大栈深度,难免显得肤浅.又比如:将一串charCode转成St ...
- @JsonInclude(Include.NON_NULL)
前端的同事要求说尽量不要有null,可有为空串“” 或者 0 或者 [], 但尽量不要null. 所以@JsonInclude(Include.NON_NULL) 这个注解放在类头上就可以解决. 实体 ...
- 全面的framebuffer详解二
转:http://blog.chinaunix.net/uid-28297667-id-3773729.html (二)一个LCD显示芯片的驱动实例 以Skeleton LCD 控制器驱动为例,在LI ...