重温WCF之消息契约(MessageContract)(六)
对于SOAP来说主要由两部分构成Header和Body,他们两个共同构成了SOAP的信封,通常来说Body保存具体的数据内容,Header保存一些上下文信息或关键信息。比如:在一些情况下,具有这样的要求:当序列化一个对象并生成消息的时候,希望将部分数据成员作为SOAP的报头,部分作为消息的主体。比如说,我们有一个服务操作采用流的方式进行文件的上载,除了以流的方式传输以二进制表示的文件内容外,还需要传输一个额外的基于文件属性的信息,比如文件格式、文件大小等。一般的做法是将传输文件内容的流作为SOAP的主体,将其属性内容作为SOAP的报头进行传递。这样的功能,可以通过定义消息契约来实现。由此可见,MessageContract的主要作用就是给我们提供了自己来操作SOAP的一种方式。
先定义我们所需要的消息协定类。
[MessageContract]
public class CarMessage
{
[MessageBodyMember]
public string CarName { get; set; }
[MessageBodyMember]
public int MakeYear { get; set; }
[MessageBodyMember]
public string SerType { get; set; }
} [MessageContract]
public class Person
{
[MessageHeader]
public string Zip { get; set; }
[MessageHeader]
public string Address { get; set; }
[MessageBodyMember]
public int Age { get; set; }
[MessageBodyMember]
public string Name { get; set; }
[MessageBodyMember]
public string Email { get; set; }
} [MessageContract]
public class RequestMessage
{
[MessageHeader]
public int maxNum;
[MessageBodyMember]
public string CheckName;
} [MessageContract]
public class ResponseMessage
{
[MessageBodyMember]
public string Name;
[MessageBodyMember]
public int CheckResult;
} [ServiceContract]
public interface IService
{
[OperationContract]
void PostMessage(CarMessage msg); [OperationContract]
Person GetPerson(); [OperationContract]
ResponseMessage CheckRenpin(RequestMessage rqmsg); } public class Service : IService
{
public void PostMessage(CarMessage msg)
{
Console.WriteLine("车子名字:{0}", msg.CarName);
} public Person GetPerson()
{
Person ps = new Person();
ps.Name = "鸟人";
ps.Age = ;
ps.Email = "nb@niube.com";
ps.Zip = "";
ps.Address = "非洲";
return ps;
} public ResponseMessage CheckRenpin(RequestMessage rqmsg)
{
ResponseMessage respMsg = new ResponseMessage();
Random rand = new Random();
respMsg.CheckResult = rand.Next(rqmsg.maxNum);
respMsg.Name = rqmsg.CheckName;
return respMsg;
} } class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Service)))
{
host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service"); //httpGetUrl客户端引用的地址
host.Description.Behaviors.Add(behavior);
host.Opened += delegate
{
Console.WriteLine("服务已启动");
Console.ReadKey();
};
host.Open();
}
}
}
确认服务器端正常运行后,在客户端添加服务引用。
在客户端生成的代理类中,消息协定和数据协定并不一样了,服务的操作协定和服务器端我们定义的不一样了。
用这种方式序列化的实体类不能当作参数直接传递,客户端会把对象的一个参数拆分为多个属性作为参数。
接下来,我们看看消息协定包含数据协定的的例子。
[DataContract]
public class ArtistInfo
{
[DataMember]
public string ArtistName;
[DataMember]
public DateTime CreateTime;
} [MessageContract]
public class Worker
{
[MessageHeader]
public ArtistInfo WorkerArtist;
[MessageBodyMember]
public string WorkerName;
[MessageBodyMember]
public string WorkerNo;
[MessageBodyMember]
public int WorkerAge;
} [ServiceContract]
public interface IService
{ [OperationContract]
void SetWorkerInformation(Worker wk); } public class Service : IService
{ public void SetWorkerInformation(Worker wk)
{
Console.WriteLine("工作名字:{0}", wk.WorkerName);
ArtistInfo info = wk.WorkerArtist;
Console.WriteLine("工人作品创建时间:{0}", info.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
Console.WriteLine("工人作品名字:{0}", info.ArtistName);
}
} class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Service)))
{
host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service"); //httpGetUrl客户端引用的地址
host.Description.Behaviors.Add(behavior);
host.Opened += delegate
{
Console.WriteLine("服务已启动");
Console.ReadKey();
};
host.Open();
}
}
}
客户端调用:
using (ServiceClient client = new ServiceClient() )
{
string name = string.Empty;
int i = client.CheckRenpin(, "aa", out name);
MessageBox.Show(i+" "+name); ArtistInfo info = new ArtistInfo();
info.ArtistName = "aaa";
info.CreateTime = DateTime.Now;
client.SetWorkerInformation(info, , "张三", "no1234");
}
重温WCF之消息契约(MessageContract)(六)的更多相关文章
- WCF 之 消息契约(MessageContract)
对于SOAP来说主要由两部分构成Header和Body,他们两个共同构成了SOAP的信封,通常来说Body保存具体的数据内容,Header保存一些上下文信息或关键信息. 比如:在一些情况下,具有这样的 ...
- C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用
我也遇到同样问题,所以抄下做MARK http://www.cnblogs.com/lmjq/archive/2011/07/19/2110319.html 刚做完一个binding为netTcpBi ...
- 重温WCF之消息拦截与篡改(八)
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...
- 重温WCF之数据契约中使用枚举(转载)(十一)
转载地址:http://www.zhuli8.com/wcf/EnumMember.html 枚举类型的定义总是支持序列化的.当我们定义一个新的枚举时,不必应用DataContract特性,就可以在数 ...
- 重温WCF之数据契约和序列化(四)
一.数据契约 1.使用数据协定可以灵活控制哪些成员应该被客户端识别. [DataContract] public class Employee { [DataMember] public string ...
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
原文:WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制 ...
- WCF把书读薄(3)——数据契约、消息契约与错误契约
上一篇:WCF把书读薄(2)——消息交换.服务实例.会话与并发 十二.数据契约 在实际应用当中数据不可能仅仅是以int Add(int num1, int num2)这种简单的几个int的方式进行传输 ...
- WCF契约之---服务契约 、数据契约、 消息契约
本篇博文只是简单说下WCF中的契约的种类.作用以及一些简单的代码示例.在WCF中契约分为服务契约.数据契约和消息契约.下面对这几种契约进行简单的介绍. 服务契约 服务契约描述了暴露给外部的类型(接口或 ...
- WCF技术剖析之十六:数据契约的等效性和版本控制
原文:WCF技术剖析之十六:数据契约的等效性和版本控制 数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据.在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交 ...
随机推荐
- 一起入门python3之元组和数列
这一节我们来说一下,元组(tupe)&数列(list).每天苦逼的工作不易啊,哎.不过呢一腔热血学习.哈哈哈哈 #井号代表注释哈. 0x01 数列-list 数列可以说是一种集合 ...
- 8 延时队列相关类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- Python自动化之socket初识
1. os.popen() os.system(cmd)会直接输出命令的结果到屏幕上,返回一个状态码0或1. os.popen(cmd)会返回一个<open file 'dir', mode ' ...
- python 内置速度最快算法(堆排)
import random import time from heapq import heappush, heappop def heapsort(iterable): h = [] for val ...
- django的序列化
关于django的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的Json格式 两种方法: 方法一:serializers: 缺点就是只能应用于对象 "&q ...
- 5.3(2)----机器人走方格2(CC150)
这道题只需要把障碍点都设为0就可以了. public static int countWays(int[][] map,int x, int y){ if( x < 0 || y < 0) ...
- MySQL一次插入多行数据
CREATE TABLE `viewhistory` ( `viewid` ) NOT NULL AUTO_INCREMENT, `uid` ) NOT NULL, `video` ) NOT NUL ...
- POJ 2570(floyd)
http://poj.org/problem?id=2570 题意:在海底有一些网络节点.每个节点之间都是通过光缆相连接的.不过这些光缆可能是不同公司的. 现在某个公司想从a点发送消息到b点,问哪个公 ...
- Android自定义图形shape
在Android开发过程中,经常需要改变控件的默认样式, 那么通常会使用多个图片来解决.不过这种方式可能需要多个图片,比如一个按钮,需要点击时的式样图片,默认的式样图片. 这样就容易使apk变大.另一 ...
- pgbouncer介绍
一.Pgbouncer 的介绍 Pgbouncer是一个针对PostgreSQL数据库的轻量级连接池,任何目标应用都可以把 pgbouncer 当作一个 PostgreSQL 服务器来连接,然后pgb ...