WCF 之 消息契约(MessageContract)
2016-08-17 15:50
295 查看
对于SOAP来说主要由两部分构成Header和Body,他们两个共同构成了SOAP的信封,通常来说Body保存具体的数据内容,Header保存一些上下文信息或关键信息。
比如:在一些情况下,具有这样的要求:当序列化一个对象并生成消息的时候,希望将部分数据成员作为SOAP的报头,部分作为消息的主体。比如说,我们有一个服务操作采用流的方式进行文件的上载,除了以流的方式传输以二进制表示的文件内容外,还需要传输一个额外的基于文件属性的信息,比如文件格式、文件大小等。一般的做法是将传输文件内容的流作为SOAP的主体,将其属性内容作为SOAP的报头进行传递。这样的功能,可以通过定义消息契约来实现。
由此可见,MessageContract的主要作用就是给我们提供了自己来操作SOAP的一种方式。
MessageContractAttribute:对控制消息头和消息体元素提供了强力支持。
所支持的属性: MessageHeaderAttribute 和 MessageBodyMemberAttribute。
用于及用途:
[1] 添加自定义头(custom headers);
[2] 控制消息是否被包装;
[3] 控制签名与加密;
一、[MessageContract]:
[1] 将一个类型转换为SOAP消息
类型可以包含消息头和消息体的元素
[2] 能够设置IsWrapped, ProtectionLevel
[3] 可以设置显式Name, Namespace
如下面的代码:
二、[MessageHeader]:
1 应用到消息契约的域(fields)或者(properties)
为创建自定义头提供了简单的方法
2 能够提供Name, Namespace, ProtectionLevel
3 可以设置SOAP协议的设置:Relay, Actor,MustUnderstand
三、[MessageBody]:
[1] 应用到消息契约的域(fields)或者属性(properties)
[2] 能够拥有多个body元素
– 等价于在操作中拥有多个参数
– 返回多个复杂类型数据的唯一方法
• 总是提供顺序(Order)
• 可以设置Name, Namespace, ProtectionLevel
那么如何应用消息契约那?不要急,下面来介绍,还是来看代码吧:
客户端
IsWrapped、WrapperName、WrapperNamespace:IsWrapped表述的含义是是否为定义的主体成员(一个或者多个)添加一个额外的根节点。WrapperName和WrapperNamespace则表述该根节点的名称和命名空间。IsWrapped、WrapperName、WrapperNamespace的默认是分别为true、类型名称和http://tempuri.org/。如果我们将IsWrapped的属性设为false,那么套在Address节点外的Customer节点将会从SOAP消息中去除。
我们在使用中发现一个特点,用这种方式序列化的实体类不能当作参数直接传递,客户端会把对象的一个参数拆分为多个属性作为参数。
比如:在一些情况下,具有这样的要求:当序列化一个对象并生成消息的时候,希望将部分数据成员作为SOAP的报头,部分作为消息的主体。比如说,我们有一个服务操作采用流的方式进行文件的上载,除了以流的方式传输以二进制表示的文件内容外,还需要传输一个额外的基于文件属性的信息,比如文件格式、文件大小等。一般的做法是将传输文件内容的流作为SOAP的主体,将其属性内容作为SOAP的报头进行传递。这样的功能,可以通过定义消息契约来实现。
由此可见,MessageContract的主要作用就是给我们提供了自己来操作SOAP的一种方式。
MessageContractAttribute:对控制消息头和消息体元素提供了强力支持。
所支持的属性: MessageHeaderAttribute 和 MessageBodyMemberAttribute。
用于及用途:
[1] 添加自定义头(custom headers);
[2] 控制消息是否被包装;
[3] 控制签名与加密;
一、[MessageContract]:
[1] 将一个类型转换为SOAP消息
类型可以包含消息头和消息体的元素
[2] 能够设置IsWrapped, ProtectionLevel
[3] 可以设置显式Name, Namespace
如下面的代码:
[MessageContract(IsWrapped=true, ProtectionLevel=ProtectionLevel.Sign)] public class SaveLinkRequest {…} [MessageContract] public class SaveLinkResponse {…}
二、[MessageHeader]:
1 应用到消息契约的域(fields)或者(properties)
为创建自定义头提供了简单的方法
2 能够提供Name, Namespace, ProtectionLevel
3 可以设置SOAP协议的设置:Relay, Actor,MustUnderstand
三、[MessageBody]:
[1] 应用到消息契约的域(fields)或者属性(properties)
[2] 能够拥有多个body元素
– 等价于在操作中拥有多个参数
– 返回多个复杂类型数据的唯一方法
• 总是提供顺序(Order)
• 可以设置Name, Namespace, ProtectionLevel
[MessageContract(IsWrapped = true, ProtectionLevel = ProtectionLevel.Sign)] public class SaveEventRequest { private string m_licenseKey; private LinkItem m_linkItem; [MessageHeader(ProtectionLevel = ProtectionLevel.EncryptAndSign)] public string LicenseKey { get { return m_licenseKey; } set { m_licenseKey = value; } } [MessageBodyMember] public LinkItem LinkItem { get { return m_linkItem; } set { m_linkItem = value; } } } [MessageContract] public class SaveEventResponse { }
那么如何应用消息契约那?不要急,下面来介绍,还是来看代码吧:
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 item = new LinkItem(); item.Id = int.Parse(this.txtId.Text); item.Title = this.txtTitle.Text; item.Description = this.txtDescription.Text; item.DateStart = this.dtpStart.Value; item.DateEnd = this.dtpEnd.Value; item.Url = this.txtUrl.Text; m_proxy.SaveGig(item); } private void cmdGet_Click(object sender, EventArgs e) { LinkItem item = m_proxy.GetGig("XXX"); if (item != null) { this.txtId.Text = item.Id.ToString(); this.txtTitle.Text = item.Title; this.txtDescription.Text = item.Description; if (item.DateStart != DateTime.MinValue) this.dtpStart.Value = item.DateStart; if (item.DateEnd != DateTime.MinValue) this.dtpEnd.Value = (DateTime)item.DateEnd; this.txtUrl.Text = item.Url; } } } }
客户端
IsWrapped、WrapperName、WrapperNamespace:IsWrapped表述的含义是是否为定义的主体成员(一个或者多个)添加一个额外的根节点。WrapperName和WrapperNamespace则表述该根节点的名称和命名空间。IsWrapped、WrapperName、WrapperNamespace的默认是分别为true、类型名称和http://tempuri.org/。如果我们将IsWrapped的属性设为false,那么套在Address节点外的Customer节点将会从SOAP消息中去除。
我们在使用中发现一个特点,用这种方式序列化的实体类不能当作参数直接传递,客户端会把对象的一个参数拆分为多个属性作为参数。
相关文章推荐
- 重温WCF之消息契约(MessageContract)(六)
- WCF开发之消息契约(MessageContract)
- 【学习】WCF的服务契约、复杂类型序列化、消息契约的实现续-IXmlSerializable与MessageContract
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
- WCF契约的简单介绍(服务契约 数据契约 消息契约)
- [原创] WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
- C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
- 【学习】WCF的服务契约、复杂类型序列化、消息契约的实现
- WCF契约的简单介绍(服务契约 数据契约 消息契约)
- WCF面向服务应用程序系列之四:契约设计(MessageContract)
- WCF把书读薄(3)——数据契约、消息契约与错误契约
- WCF契约的简单介绍(服务契约 数据契约 消息契约)
- WCF契约的简单介绍(服务契约 数据契约 消息契约)
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
- WCF 第二章 契约 消息契约
- 消息契约(MessageContract)和消息Message类
- WCF契约的简介(服务契约、数据契约和消息契约)
- WCF中的消息契约
- WCF契约之---服务契约 、数据契约、 消息契约