WCF的契约主为分为:服务契约、数据契约、消息契约,其中数据契约包括:可序列化的数据类型和已知类型。而我们在设计契约时,则主要采用三种方式:明确契约(ExplicitContract)、已知类型契约(KnownTypesContract)和消息契约(MessageContract)。
开发环境:Visual Studio 2010 + Net Framework 4.0 。
明确契约(ExplicitContract):在标明契约时提供显示的Name、提供命名空间(Web service的规范要求使用“schemas”前缀来表示服务目标的命名空间),对于数据契约则可以通过IsRequired来指定此属性是否是必须的,Order来指定显示的顺序。
IsRequired:在服务端版本升级时为了兼容客户端,则可以把新添加的数据属性在DataMember中指定IsRequired=false;若新添加的数据属性指明为true,此时,如果由于缺少相应的值则会抛出异常。
下面通过代码来演示明确契约:
1、创建一个WCF Service Library程序,修改解决方案名称为ContractDesign,修改项目名称为ExplicitContract,删除自动添加的文件。
2、新建Item.cs类,代码如下:
[DataContract(Name = "ItemContract", Namespace = "http://schemas.xinhaijulan.com/demos/ExplicitContract")]
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; }
}
对于类Item在客户端调用时不会显示Item而是显示ItemContract,数据成员亦同。
在使用WCF契约时,必须引入相应的命名空间:using System.Runtime.Serialization;using System.ServiceModel; 以下亦同。
3、创建服务接口文件IExplicitService.cs,代码如下:
[ServiceContract(Name = "ExplicitServiceContract", Namespace = "http://schemas.xinhaijulan.com/demos/ExplicitContract")]
public interface IExplicitService
{
[OperationContract(Name = "SaveItemContract")]
void SaveItem(Item item);
[OperationContract(Name = "GetItemContract")]
Item GetItem();
}
对于方法SaveItem在客户端调用时将会以SaveItemContract的名称调用,其它亦同。
4、创建ExplicitService.cs类文件,代码如下:
public class ExplicitService : IExplicitService
{
private Item _item;
public void SaveItem(Item item)
{
this._item = item;
}
public Item GetItem()
{
this._item.Message = "IExplicitService.GetItem() invoked.";
return this._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="ExplicitContract.ExplicitService">
<endpoint address="" binding="wsHttpBinding" contract="ExplicitContract.IExplicitService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/ExplicitContract/ExplicitService/" />
</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,修改名称空间为TestExplicitContract,并添加测试TestExplicitContract方法,代码如下:
static void Main(string[] args)
{
TestExplicitContract();
Console.ReadLine();
}
private static void TestExplicitContract()
{
Console.WriteLine("-----------------Test ExplicitContract Begin-----------------");
ExplicitContract.ExplicitServiceContractClient client = new ExplicitContract.ExplicitServiceContractClient();
//ExplicitDataContract
ExplicitContract.ItemContract item = null;
string readValue = "";
Console.WriteLine("Input exit to close the client, others continue.");
readValue = Console.ReadLine();
while (readValue != "exit")
{
//ExplicitDataContract
item = new ExplicitContract.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);
//ExplicitServiceContract
client.SaveItemContract(item);
//ExplicitServiceContract
item = client.GetItemContract();
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 ExplicitContract End-----------------");
}
private static int GetInt(object obj)
{
int i = 0;
if (obj != null)
{
int.TryParse(obj.ToString(), out i);
}
return i;
}
7、设置Client为启动项目,运行调试ExplicitContract程序,然后,将在控制台看到如下输出:
-----------------Test ExplicitContract Begin-----------------
Input exit to close the client, others continue.
Please input the id:
123
You have input item.IdContract:123
Please input the name:
xinhaijulan
You have input item.NameContract:xinhaijulan
Get from server item.IdContract is : 123
Get from server item.NameContract is : xinhaijulan
Get from server item.MessageContract is : IExplicitService.GetItem() invoked.
----------------------------------------------
Input exit to close the client, others continue.
至此,WCF契约设计—ExplicitContract介绍完毕,下一章将介绍WCF契约设计(KnownTypesContract) 。
Demo下载将在契约设计介绍全部完成时提供。请到【契约设计(MessageContract)】下载DEMO。
作者:心海巨澜
出处:http://xinhaijulan.cnblogs.com
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。