WCF初探-19:WCF消息协定
WCF消息协定概述
- 在生成 WCF应用程序时,开发人员通常会密切关注数据结构和序列化问题,而不必关心携带数据的消息结构。 对于这些应用程序,为参数或返回值创建数据协定的过程很简单。但是,有时完全控制 SOAP 消息的结构与控制其内容一样重要。 当必须提供互操作性或需要在消息或消息部分级别特别控制安全问题时,更是如此。 在这些情况下,您可以创建消息协定 ,使您可以指定所需的精确的 SOAP 消息的结构。
- 一般来说,定义消息的架构时使用数据协定就足够了。但是,有时必须精确控制如何到通过网络传输的 SOAP 消息的结构。对于这种情况,最常见的方案是插入自定义 SOAP 标头。另一种常见方案是定义消息头和正文的安全属性,也就是说,确定是否对这些元素进行数字签名和加密。消息样式的操作可提供这种控制。
创建消息协定
- 消息样式的操作最多具有一个参数和一个返回值,其中参数和返回值的类型都是消息类型;也就是说,这两种类型可直接序列化为指定的 SOAP 消息结构。这可以是用 MessageContractAttribute 标记的任何类型或 Message 类型。
- 若要为某一类型定义消息协定(即定义该类型和 SOAP 信封之间的映射),请对该类型应用 MessageContractAttribute。 然后对该类型中要成为 SOAP 标头的成员应用 MessageHeaderAttribute,并对要成为消息的 SOAP 正文部分的成员应用 MessageBodyMemberAttribute。
- 可以对所有字段、属性和事件应用 MessageHeaderAttribute 和 MessageBodyMemberAttribute,而不管这些字段、属性和事件是公用的、私有的、受保护的还是内部的。
WCF消息协定示例
- 解决方法结构如下:
- 工程结构说明:
- Service:类库程序,WCF服务端程序。在服务协定接口IuserInfo.cs中定义了消息协定User类型的类,其中属性OprationType和OperationTime定义为消息标头,其他属性定义为消息正文。定义操作协定GetInfo(),返回消息协定User。IUserInfo.cs代码如下:
using System;
using System.ServiceModel;
using System.Collections.Generic;
using System.Runtime.Serialization; namespace Service
{
[ServiceContract]
public interface IUserInfo
{
[OperationContract]
User GetInfo();
} [MessageContract]
public class User
{
[MessageHeader]
public string OprationType { get; set; }
[MessageHeader]
public DateTime OperationTime { get; set; } [MessageBodyMember]
public int ID { get; set; }
[MessageBodyMember]
public string Name { get; set; }
[MessageBodyMember]
public int Age { get; set; }
[MessageBodyMember]
public string Nationality { get; set; }
}
}
UserInfo.cs代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Service
{
public class UserInfo:IUserInfo
{
public User GetInfo()
{
User user = new User();
user.OprationType = "GET";
user.OperationTime = System.DateTime.Now;
user.Name = "JACK";
user.Age = ;
user.ID = ;
user.Nationality = "CHINA"; return user;
}
}
}
2. Host:控制台应用程序,服务承载程序。添加对程序集Service的引用,完成以下代码,寄宿服务。Program.cs代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel; namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(UserInfo)))
{
host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };
host.Open();
Console.Read();
}
}
}
}
App.config代码如下:
<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.UserInfo" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/UserInfo/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="Service.IUserInfo" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
我们通过svcutil.exe工具生成客户端代理类和客户端的配置文件,注意,此处生成的客户端代理类型为消息协定类型,所以需要在svcutil.exe的参数后追加/mc才能生成消息协定的客户端代理类。
svcutil.exe是一个命令行工具,位于路径C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin下,我们可以通过命令行运行该工具生成客户端代理类
- 在运行中输入cmd打开命令行,输入 cd C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
- 输入svcutil.exe /out:f:\UserInfoClient.cs /config:f:\App.config http://localhost:1234/UserInfo /mc
3. Client:控制台应用程序,客户端调用程序。将生成的UserInfoClient.cs和App.config复制到Client的工程目录下,完成客户端调用代码。Program.cs的代码如下:
using System; namespace Client
{
class Program
{
static void Main(string[] args)
{
UserInfoClient proxy = new UserInfoClient();
User user = proxy.GetInfo(new GetInfoRequest());
Console.WriteLine("{0,-10}{1,-20}{2,-10}{3,-10}{4,-10}{5,-10}",
"Type","Time","ID", "Name", "Age", "Nationality"); Console.WriteLine("{0,-10}{1,-20}{2,-10}{3,-10}{4,-10}{5,-10}",
user.OprationType.ToString(),
user.OperationTime.ToString(),
user.ID.ToString(),
user.Name.ToString(),
user.Age.ToString(),
user.Nationality.ToString()); Console.Read();
}
}
}
程序运行结果如下:
总结:
- 通过示例,我们完成了对消息协定的创建和调用。接下来我们可以利用WCF客户端测试程序来查看消息协定存在于消息中的位置。在开始菜单中找到visual studio 2010的安装目录Visual studio Tools中的visual studio命令提示工具,输入wcftestclient命令,在WCF客户端测试中添加服务地址http://localhost:1234/UserInfo/引用,添加成功后,点击GetInfo方法的调用按钮,查看调用返回的消息。在其中,我们看到了属性OprationType和OperationTime显示在了消息头的部分,而其他的属性显示在了消息正文的部分。
在生成消息客户端代理类时,我们追加了一个/mc的参数,当我们查看客户端代理类UserInfoClient.cs的代码时会发现,客户端生成的消息协定按照服务端消息协定的定义被MessageContractAttribute和MessageHeaderAttribute以及MessageBodyMemberAttribute修饰了。但是操作协定的GetInfo却多出了一个类型为GetInfoRequest参数。所以我们在客户端调用的时候,还要new 一个 GetInfoRequest参数类型,才能调用GetInfo方法。
WCF初探-19:WCF消息协定的更多相关文章
- WCF初探文章列表
WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...
- WCF初探-22:WCF中使用Message类(上)
前言 从我们学习WCF以来,就一直强调WCF是基于消息的通信机制.但是由于WCF给我们做了高级封装,以至于我们在使用WCF的时候很少了解到消息的内部机制.由于WCF的架构的可扩展性,针对一些特殊情况, ...
- WCF初探-14:WCF服务协定
前言: 在前面的文章中,我们定义的服务协定上都会有一个ServiceContract的特性来修饰,这是因为服务契约的实现要靠ServiceContractAttribute 属性定义,然后使用一个或多 ...
- WCF初探-15:WCF操作协定
前言: 在前面的文章中,我们定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationCo ...
- WCF初探-20:WCF错误协定
WCF错误协定概述 在所有托管应用程序中,处理错误由 Exception 对象表示. 在基于 SOAP 的应用程序(如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息. SO ...
- WCF学习心得------(七)消息协定
第七章 消息协定 7.1 消息协定概述 通常情况下,在定义消息的架构时只使用数据协定就足够,但是有时需要精确控制如何将类型映射到通过网络传输的SOAP消息.对于这种情况,通常解决方案是插入自定义的SO ...
- 传说中的WCF(8):玩转消息协定
Message翻译成中文,相信各位不陌生,是啊,就是消息,在WCF中也有消息这玩意儿,不知道你怎么去理解它.反正俺的理解,就像我们互发短信一个道理,通讯的双方就是服务器与客户端,说白了吧,就是二者之间 ...
- WCF基础之消息协定
通常定义消息的架构,使用数据协定就够了,但是有时必须将类型精确映射到soap消息,方法两种:1.插入自定义soap标头:2.另一种是定义消息的头和正文的安全属性.消息协定通过MessageContra ...
- 我们一起学习WCF 第五篇数据协定和消息协定
A:数据协定(“数据协定”是在服务与客户端之间达成的正式协议,用于以抽象方式描述要交换的数据. 也就是说,为了进行通信,客户端和服务不必共享相同的类型,而只需共享相同的数据协定. 数据协定为每个参数或 ...
随机推荐
- Dijkstar算法的数学原理
Dijkstar算法是荷兰数学家迪克斯屈拉(or迪杰斯特拉?)在1959年发现的一个算法.是现有的几个求带权图中两个顶点之间最短通路的算法之一.算是一个相当经典的算法了. 迪克斯屈拉算法应用于无向连通 ...
- Dedesql数据库类详解
今天花点时间讲解下织梦的sql数据库类,近期本来是准备录制一套视频教程的,但由于视频压缩的问题迟迟没有开展工作,如果大家有什么好的视频压缩方式可以通过邮件的方式告诉我:tianya#dedecms.c ...
- 在CentOS 7上安装Node.js的4种方法
一.源码安装 1.下载源码(官网查看最新版本链接) wget http://nodejs.org/dist/v0.10.30/node-v0.10.30.tar.gz 2.解压源码 tar xzvf ...
- Groovy学习笔记(二)
在上一篇文章中我们主要学习了如何搭建Groovy开发环境,为我们的Groovy之旅做好了准备工作,不知道你是否准备好了?接下来我们就一起看看Groovy与我们熟悉的Java有什么异同. Groovy是 ...
- meta标签详解(meta标签的作用)///////////////////////////转
meta标签详解(meta标签的作用) 很多人却忽视了HTML标签META的强大功效,一个好的META标签设计可以大大提高你的个人网站被搜索到的可能性,有兴趣吗,谁我来重新认识一下META标签吧 ...
- objective-c第六章课后练习6
题6:接受从终端输入的整数,提取并用英语显示这个数的每一个数字,如932,显示nine three two (题目中注了.这个练习很难)的确有点难,自己想了很久网上也各种搜索.也算是找到参考了 cod ...
- Python之通过IP地址库获取IP地理信息
利用第三方的IP地址库,各个公司可以根据自己的业务情况打造自己的IP地址采集分析系统.例如游戏公司可以采集玩家地区信息,进行有针对性的运营策略,还可能帮助分析玩家网络故障分布等等. #!/usr/bi ...
- iOS 编码规范
Coding Guidelines for Cocoa https://developer.apple.com/library/prerelease/content/documentation/Coc ...
- SSH服务器拒绝密码检测
这两天在配置Ubuntu 14.04的环境时,碰到一个典型的问题:在用xshell 连接Ubuntu时,显示"SSH服务器拒绝密码检测"的问题,在经过一系列配置修改后,最终怀疑是否 ...
- python学习总结1
1.python环境搭建 1.下载python并安装,下载地址:http://pan.baidu.com/s/1jHpWblk 2.启动idle即可编辑python代码 2.基本语法 1.注释:单行注 ...