上一章我们介绍了契约设计中的已知类型契约(KnownTypesContract),这一章我们介绍:消息契约(MessageContract)。
消息契约(MessageContract):对控制消息头和消息体元素提供了强力支持,支持MessageHeaderAttribute和MessageBodyMemberAttribute属性。可以添加自定义头,控制消息是否被包装(IsWrapped),以及控制签名与加密(ProtectionLevel)。
开发环境:Visual Studio 2010 + Net Framework 4.0 。
下面通过代码来演示消息契约:
1、新增一个WCF Service Library程序,修改项目名称为MessageContract,删除自动添加的文件。
2、新建Item.cs类,代码如下:
[DataContract(Name = "ItemContract", Namespace = "http://schemas.xinhaijulan.com/demos/MessageContract")]
public class Item
{
[DataMember(Name = "IdContract", IsRequired = true, Order = 0)]
public int Id { get; set; }
[DataMember(Name = "NameContract", IsRequired = true, Order = 1)]
public string Name { get; set; }
[DataMember(Name = "MessageContract", IsRequired = true, Order = 2)]
public string Message { get; set; }
}
3、添加消息契约类,代码如下:
[MessageContract(IsWrapped = true, ProtectionLevel= ProtectionLevel.EncryptAndSign)]
public class SaveRequest
{
[MessageBodyMember]
public Item Item { get; set; }
}
[MessageContract(IsWrapped = false)]
public class SaveResponse
{
}
[MessageContract(IsWrapped=false)]
public class GetRequest
{
[MessageHeader]
public string LicenseKey { get; set; }
}
[MessageContract(IsWrapped = false)]
public class GetResponse
{
public GetResponse()
{
}
public GetResponse(Item item)
{
this.Item = item;
}
[MessageBodyMember]
public Item Item { get; set; }
}
消息契约用到了:MessageContract、MessageHeader、MessageBodyMember标记。
3、新建WCF接口文件IMessageService.cs,代码如下:
[ServiceContract(Name = "MessageContract", Namespace = "http://schemas.xinhaijulan.com/demos/MessageContract")]
public interface IMessageService
{
[OperationContract]
SaveResponse SaveItem(SaveRequest requestMessage);
[OperationContract]
GetResponse GetItem(GetRequest requestMessage);
}
4、新建MessageService.cs类,代码如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MessageService : IMessageService
{
private Item _item;
public SaveResponse SaveItem(SaveRequest requestMessage)
{
this._item = requestMessage.Item;
return new SaveResponse();
}
public GetResponse GetItem(GetRequest requestMessage)
{
if (requestMessage.LicenseKey != "xinhaijulan")
{
throw new FaultException("Invalid license key.");
}
_item.Message = "MessageService is invoked.";
return new GetResponse(_item);
}
}
5、修改App.config中的服务名称 、端点契约、服务地址,代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="MessageContract.MessageService">
<endpoint address="" binding="wsHttpBinding" contract="MessageContract.IMessageService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MessageContract/MessageService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
6、在客户端控制台程序Client中,添加Service Reference,修改名称空间为MessageContract,并添加测试TestMessageContract方法,代码如下:
private static void TestMessageContract()
{
Console.WriteLine("-----------------Test MessageContract Begin-----------------");
MessageContract.MessageContractClient client = new MessageContract.MessageContractClient();
MessageContract.ItemContract item = null;
string readValue = "";
Console.WriteLine("Input exit to close the client, others continue.");
readValue = Console.ReadLine();
while (readValue != "exit")
{
item = new MessageContract.ItemContract();
Console.WriteLine("Please input the id:");
item.IdContract = GetInt(Console.ReadLine());
Console.WriteLine("You have input item.IdContract:{0}", item.IdContract);
Console.WriteLine("Please input the name:");
item.NameContract = Console.ReadLine();
Console.WriteLine("You have input item.NameContract:{0}", item.NameContract);
client.SaveItem(item);
item = client.GetItem("xinhaijulan");
if (item != null)
{
Console.WriteLine();
Console.WriteLine("Get from server item.IdContract is : {0}", item.IdContract);
Console.WriteLine("Get from server item.NameContract is : {0}", item.NameContract);
Console.WriteLine("Get from server item.MessageContract is : {0}", item.MessageContract);
}
Console.WriteLine("----------------------------------------------");
Console.WriteLine("Input exit to close the client, others continue.");
readValue = Console.ReadLine();
}
client.Close();
Console.WriteLine("-----------------Test MessageContract End-----------------");
}
7、设置Client为启动项目,运行调试MessageContract程序,然后,将在控制台看到如下输出:
-----------------Test MessageContract Begin-----------------
Input exit to close the client, others continue.
Please input the id:
456
You have input item.IdContract:456
Please input the name:
xinhaijulan
You have input item.NameContract:xinhaijulan
Get from server item.IdContract is : 456
Get from server item.NameContract is : xinhaijulan
Get from server item.MessageContract is : MessageService is invoked.
----------------------------------------------
至此,WCF契约设计全部介绍完毕,下一章将介绍WCF的契约版本。
作者:心海巨澜
出处:http://xinhaijulan.cnblogs.com
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。