消息协定概述
通常,定义消息的架构时使用数据协定就足够了。但有时必须精确控制如何将类型映射到通过网络传输的SOAP消息。
对于这种情况,最常见的方案是插入自定义SOAP标头。另一种常见方案是定义消息头和正文的安全属性,也就是说,确定是否对这些元素进行数字签名和加密。消息样式的操作可提供这种控制。
消息样式的操作
最多具有
一个参数和一个返回值,其中参数和返回值的类型都是消息类型都是
消息类型;也就是说,这两种类型可直接序列化为指定的SOAP消息结构。
可以用MessageContractAttribute标记的任何类型或Message类型。
返回值为void是有效的;而且没有传入参数,但有返回的消息参数也是有效的。
若要为某一类型定义消息协定(即定义该类型和SOAP信封之间的映射)请对该类型应用MessageContractAttribute。然后对该类型中要成为SOAP标头的成员应用MessageHeaderAttribute,并对要成为消息的SOAP正文部分的成员应用MessageBodyMemberAttribute。
以MessageContractAttribute标记的类,可以用来作为以消息方式来传输数据到客户端的承载类型,并且WCF基础结构可以去序列化它
[MessageContract] //定义消息协定类
public class BankingTransaction
{
[MessageHeader] //定义消息头字段
public Operation operation;
[MessageHeader]
public DateTime transactionDate;
[MessageBodyMember] //定义消息正文字段
private Account sourceAccout;
[MessageBodyMember]
private Account targetAccount;
[MessageBodyMember]
public int amount;
}
DEMO
1) 新创建一个"Video7.Demo1.Message“的WCF Service Application项目,删除默认生成的service1.svc后,手动添加”WCF Service“服务——CalculatorService服务类,然后再ICalculatorService.cs里定义WCF服务接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace Video7.Demo1.Message
{
//定义服务协定
[ServiceContract(Namespace = "http://Video7.Demo1.Message")]
public interface ICalculatorService
{
[OperationContract(Action = "http://test/MyMessage_action", ReplyAction = "http://test/MyMessage_action")]
//服务方法接受消息协定类型的参数,并且返回一个消息协定的类型MyMessage
MyMessage Calculator(MyMessage request);
}
}
2) 创建MyMessage类型的消息协定类型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Video7.Demo1.Message
{
//定义消息协定类 可以用来作为以消息方式来传输数据到客户端的承载类型,并且WCF基础结构可以去序列化它
[MessageContract]
public class MyMessage
{
private string operation;
private double n1;
private double n2;
private double result;
//构造方法——创建一个空的message对象
public MyMessage()
{
}
//构造方法——创建带有参数的构造函数
public MyMessage(double n1,double n2, string operation,double result)
{
this.n1 = n1;
this.n2 = n2;
this.operation = operation;
this.result = result;
}
//构造方法——创建传递message类型参数的构造方法
public MyMessage(MyMessage message)
{
this.n1 = message.n1;
this.n2 = message.n2;
this.operation = message.operation;
this.result = message.result;
}
//定义标头成员
[MessageHeader]
public string Operation
{
get { return operation; }
set { operation = value; }
}
//定义消息正文成员
[MessageBodyMember]
public double N1
{
get { return n1; }
set { n1 = value; }
}
//定义消息正文成员
[MessageBodyMember]
public double N2
{
get { return n2; }
set { n2 = value; }
}
//定义消息正文成员
[MessageBodyMember]
public double Result
{
get { return result; }
set { result = value; }
}
//定义消息标头成员
[MessageHeader(MustUnderstand = true)]
public string str;
}
}
3) 实现WCF服务接口类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace Video7.Demo1.Message
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Calculato