编写您的第一个 WCF 服务






2.92/5 (21投票s)
2007年4月28日
5分钟阅读

128865

2624
本文有助于编写第一个 WCF 服务
在尝试示例之前,请确保您已安装 .NET Framework 3.0 可再发行组件包和 Microsoft® Windows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components。
引言
WCF 是 .NET 3.0 中用于跨计算机对象通信的方式。它基于 WSDL。WCF 服务在开始为您工作之前需要正确完成一些事情。以下几点以最简短的术语描述了所有的技术术语。
在深入实际工作之前,让我们先了解一下基础知识。我将尽量使它们直观简单。
WCF 基础知识
流行的 ABC
这是理解 WCF 如何工作的流行方式。A 是地址 (Address),B 是绑定 (Binding),C 是契约 (Contract)。
- 地址 (Address) 是你进行通信的地方。它不像部署服务的位置,而是用于内部映射你的请求和响应的 URL。
- 绑定 (Binding) 是你如何通信。有几种默认的绑定,如 BasicHttp、TCP、NamedPipes、MSMQ 等。这是服务器和客户端在通信时理解的协议。
- 契约 (Contract) 是你通信的内容。有关契约的详细信息,请参阅下一节。
合同
有两种类型的契约
- 服务契约 (Service Contracts): 这是服务消费者在你的服务上调用的 API。它是将进入 WSDL 的方法签名。
- 数据契约 (Data Contracts): 这是将从服务消费者和到服务传输的数据。它是数据结构。这可以在你的服务的 schema 中找到。
还有一种叫做消息契约 (Message Contract) 的东西,它基本上是一种使用消息而不是严格类型化结构进行通信的方式。有很多你想使用它的情况,但这超出了本文的范围。
托管
有三种方式可以托管你的服务。
- 自托管 (Self hosting): 服务将自行托管并监听客户端请求并进行响应。
- IIS 托管 (IIS hosting): 到目前为止,这是最流行的一种。IIS 将托管你的服务(就像你的 ASMX 服务一样)。
- WAS 托管 (WAS hosting): 这仅适用于 Windows Vista,并且比其他方法提供了许多优点,但这超出了本文的范围。
既然你已经有了 WCF 的基本信息,我们来构建一个。
开发第一个应用程序
你想做的第一件事就是准备好你的服务,以便客户端可以开始使用它。
开发服务
通过定义你的数据结构来创建你的数据契约。
[DataContract]
public class Request
{
string name;
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
[DataContract]
public class Response
{
string message;
[DataMember]
public string Message
{
get { return message; }
set { message = value; }
}
}
我们基本上编写了两个类,但指定了 DataContract
和 DataMember
属性,这使得它们对 WCF 来说是特殊的。
现在,让我们通过定义 API 签名来创建一个服务契约。
[ServiceContract]
public interface ISampleService
{
[OperationContract]
Response GetMessage ( Request request );
[OperationContract]
String SayHello();
}
在上面的代码中,我定义了两个服务契约,一个使用数据契约,另一个使用本机数据结构 (string
)。就这样,很简单。
现在我们已经准备好了结构,我们将去构建我们的服务。
[ServiceBehavior]
public class Service: ISampleService
{
[OperationBehavior]
public Response GetMessage ( Request request )
{
Response response = new Response();
if ( null == request )
response.Message = "Error!";
else
response.Message = "Hello, " + request.Name;
return response;
}
[OperationBehavior]
public string SayHello()
{
return "Hello, World!";
}
}
同样,我们这里没有做什么不同的事情。只是向 service
类添加了 ServiceBehavior
属性,并继承了 ServiceContract
interface
。事实上,添加 ServiceBehavior
属性是可选的。你所要做的就是让你的 service
类派生自服务契约。
现在我们已经开发了服务,我们应该托管它,以便消费者可以开始使用它。我将向你展示如何在 IIS 中托管它,因为我认为这是最常见的。
要在 IIS 中托管服务,我们需要两样东西。一个配置文件和一个服务宿主文件 (.svc)。
配置文件是我们定义 ABC 的地方,svc 文件是我们定义服务的地方,也将是我们的消费者的联系点。
//web.config file excerpts
<system.serviceModel>
<services>
<service name="SampleService.Service"
behaviorConfiguration="SampleServiceBehavior">
<endpoint address="" binding="basicHttpBinding"
contract="SampleService.ISampleService"/>
<endpoint contract="IMetadataExchange"
binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SampleServiceBehavior">
<serviceDebug includeExceptionDetailInFaults ="true"/>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
//svc file excerpts
<% @ServiceHost Language=C# Service="SampleService.Service" %>
你必须添加引用,服务程序集。
配置文件中的服务行为基本上指示运行时在通过 HttpGet
协议查询时包含元数据。
现在,我们的服务已经完成。只需在浏览器中打开 svc 文件,看看一切是否看起来正常。你应该会看到通过 IIS 或 VS Web Server 浏览的文件。
开发客户端
我们现在将重点关注如何为此服务开发客户端。
我们现在需要创建一个代理来与服务通信。这里有 Visual Studio 会有帮助,如果没有,我们可以使用 svcutil.exe 来生成代理。
我自己编写了代理,因为这让我有自由来减少 svcutil 放入的不必要的东西。我将跳过代理,因为它与 servicecontract
、datacontract
和服务存根非常相似。
VS 会自动生成一个配置文件,看起来像
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISampleService"
closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32"
maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName"
algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address=https://:4161/ServiceHost/Service.svc
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISampleService"
contract="SampleService.ISampleService"
name="BasicHttpBinding_ISampleService" />
</client>
</system.serviceModel>
</configuration>
这基本上指定了超时、内容长度和其他基本信息,并且这些元素的解释超出了本文的范围。
这里有趣的点是 endpoint 元素及其属性。这里的地址指的是我们创建和托管的svc 文件,绑定应该与服务器绑定相同。如果你想指定多个绑定,你可以这样做。但服务器首先应该为此做好准备。最后,契约指定了要在服务器上执行的代码。
客户端应用程序就像使用代理公开的 API 一样简单,看起来像
static void Main( string[] args )
{
Request request = new Request();
request.Name = "Sidhu";
SampleServiceClient service = new SampleServiceClien
( "BasicHttpBinding_ISampleService" );
Console.WriteLine( service.SayHello() );
Response response = service.GetMessage( request );
Console.Write( response.Message );
Console.ReadKey();
}
这里唯一要考虑的是 endpoint 名称应该与配置文件中的名称相同。
摘要
执行程序,然后在屏幕上看到 Hello, World!
对于一个简单的程序来说,这已经不少了,但值得开始,因为它的潜力是巨大的。
请对本文留下反馈/建议/评论。如果你想要包含此代码的工作解决方案,请发送一封主题行为“源文件:第一个 WCF 示例”的邮件。这将帮助我进行筛选并及时回复。