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岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经> ...
随机推荐
- king's trouble II SCU - 4488
Time Limit: 1000 MS Memory Limit: 131072 K Description Long time ago, a king occupied a vast territo ...
- C和指针之学习笔记(1)
第1章 1.输入字符串 while((ch=getchar())!=EOF && ch!=’\n’) ; ch=getchar() while(ch!=EOF && ...
- 【UOJ #105】【APIO2014】Beads and wires
http://uoj.ac/problem/105 好神的dp啊. 确定一个点为根之后,蓝线只能是竖着的,不能横跨兄弟. 枚举每个点为根进行树形dp是\(O(n^2)\)的,\(f(x,0/1)\)表 ...
- 数据离散化 ( 以及 stl 中的 unique( ) 的用法 )+ bzoj3289:Mato的文件管理
http://blog.csdn.net/gokou_ruri/article/details/7723378 ↑惯例Mark大神的博客 bzoj3289:Mato的文件管理 线段树求逆序对+莫队 ...
- [CodeForces-441E]Valera and Number
题目大意: 给你一个数x,进行k次操作: 1.有p%的概率将x翻倍: 2.有1-p%的概率将x加1. 问最后二进制下x末尾0个数的期望. 思路: 动态规划. 由于k只到200,所以每次修改只与最后8位 ...
- 区间DP POJ 1141 Brackets Sequence
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29520 Accepted: 840 ...
- Bellman-ford 算法详解
昨天说的dijkstra固然很好用,但是却解决不了负权边,想要解决这个问题,就要用到Bellman-ford. 我个人认为Bellman-Ford比dijkstra要好理解一些,还是先上数据(有向图) ...
- Linux下Apache2.2和PHP5的安装配置
Linux下Apache2.2和PHP5的安装配置 环境介绍 我安装使用的Linux版本为CentOS6.5最精简版,Apache为2.2.29,PHP版本为5.4.28. 系统安装 首先安装Cent ...
- 实用在线小工具 -- JS代码压缩工具
实用在线小工具 -- JS代码压缩工具 将JS代码进行压缩可以减少内存占用,下面链接是一个在线JS代码压缩工具,它将多余的空格和换行符压缩了. JS代码压缩工具链接:http://jspack ...
- asp.net调用存储过程1
1,传入参数,传出参数 public int GetTeam1Id(string userId) { int team1ID = -1; st ...