1. 开发服务(Service)
(1)新建WCF服务应用程序
WCF是.NET3.0新增的,如果要在Visual Studio 2005下开发WCF应用程序,需要安装Visual Studio 2005 Extensions for WCF and WPF才可以支持。Visual Studio 2008 和 2010 由于包含了.NET3.0,所以,它直接支持创建WCF服务项目。
(2)定义WCF服务契约
新建WCF服务应用程序后,系统会自动生成IService1.cs文件,如下代码所示。它是服务契约接口文件。服务要实现的操作可以通过接口来定义。(将红体部分修改为自己的业务代码)
//IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService1
{
// 注意: 如果更改此处的接口名称 "IService1",也必须更新 Web.config 中对 "IService1" 的引用。
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// 任务: 在此处添加服务操作
}
// 使用下面示例中说明的数据约定将复合类型添加到服务操作。
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
服务契约需要用 [ServiceContract]属性定义,使它成为WCF服务中公开的接口。
服务定义的操作方法用 [OperationContract] 属性定义,使它成为WCF服务公开接口中公开的成员。
实体类CompositeType是通过服务发送的复合类型的数据契约定义的,有[DataContract]和[DataMember]属性定义。
(3)实现WCF服务契约
服务实现,其实就是对契约(接口)的实现,继承接口并实现方法。(下面代码是系统自动生成的,把红色部分改为自己的代码)
//Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService1
{
// 注意: 如果更改此处的类名“Service1”,也必须更新 Web.config 和关联的 .svc 文件中对“Service1”的引用。
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
重新编译WCF服务应用程序,会发现WcfService1\bin 的目录下生成了WcfService1.dll,说明刚才我们创建的WCF服务应用程序其实是个类库项目。
2. 创建宿主进程(Host)
要想使WCF服务运行,需要宿主进程(Host)。即WCF服务不可能凭空存在。每个WCF服务必须托管(Hosting)在Windows进程中,该进程就称为宿主进程(Host Process)。宿主可以由IIS提供,也可以由Windows Form程序或Windows服务提供,或者Console控制台程序也可以。
下面以Windows Form程序为示例进行讲解,其他方法基本类似。具体步骤:
(1)新增一个WindowsForms应用程序WindowsFormsWcfApp。
(2)在WindowsFormsWcfApp中添加对刚才实现的WCF服务的WcfService1库引用。
(3)添加引用:System.ServiceModel;
(4)配置宿主程序WindowsFormsWcfApp的参数。
添加一个应用程序配置文件App.config。并加入如下配置:
//App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" />
</service>
</services>
<!--为了调试,设置includeExceptionDetailInFaults属性等于true.-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
整个WCF配置是用system.serviceModel元素定义的。
服务用<service>元素定义,<service>包括一个指定契约的<endpoint>元素,契约的值是指定了[ServiceContract]属性的接口的名称,包括接口的命名空间,如contract="WcfService1.IService1"。属性binding指定了绑定信息定义了由服务使用的协议,"wsHttpBinding"代表了WCF服务使用的是HTTP协议。
<host>元素定义了服务的地址,服务可以用http://localhost:8000/寻址。
(5)启动服务
向WindowsFormsWcfApp的Form1窗体添加两个Button按钮,如下图所示,并完善Form1.cs文件
//Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
namespace WindowsFormsWcfApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//声明宿主
ServiceHost host = null;
private void btnStart_Click(object sender, EventArgs e)
{
host = new ServiceHost(typeof(WcfService1.Service1));
host.Open(); //启动服务的监听器信道,监听请求
lblShow.Text = "服务已启动";
}
private void btnStop_Click(object sender, EventArgs e)
{
if (host.State != CommunicationState.Closed)
{
host.Close(); //停止信道
}
lblShow.Text = "服务已停止";
}
}
}
运行该宿主程序,单击“启动服务”按钮在IE浏览器栏中输入:http://localhost:8000/,将会看到下图所示的服务提示信息。
3. 创建WCF客户端
若要调用WCF服务的操作,则客户端首先需要导入服务契约到客户端本地描述(Native Representation)中。如果客户端使用WCF,则调用操作的常见做法是使用代理。代理是一个CLR类,它公开了一个单独的CLR接口用以表示服务的契约。代理完全封装了服务的每一个方面:服务的位置、实现技术、运行时平台及通信传输。
(1)生成代理类和配置文件
方式一:直接添加服务引用,如下图
添加服务引用时必须确定WCF服务端正在运行中,否则地址无法访问。
方式二:通过命令行工具SvcUtil.exe生成代理。
我们知道Web Service是通过WSDL对外提供服务的描述,以便客户端能够通过WSDL知道这个Web Service所包含的方法、方法的签名等信息,客户端通过WSDL就能知道怎么去调用这个Web Service。
到了WCF,微软依然采用WSDL来提供WCF服务描述。
前面服务端宿主程序的配置,添加了一个 <serviceMetadata httpGetEnabled="True"/>,目的就是让服务端对外提供WSDL形式的服务Metadata描述。
微软也提供了Secutil.exe工具来通过WSDL生成客户端代理类和契约配置文件。
选择菜单“开始”--->“Microsoft Visual 2008”--->"Visual Studio Tools"--->"Visual Studio 2008命令提示"命令。启动VS2008的命令行窗口。
输入:svcutil.exe/language:c#/out:Client.cs/config:app.config。
该命令指定了要生成代码的语言、代理类代码文件和配置文件名,以及WCF服务端的地址。
命令运行时必须确定WCF服务端正在运行中。
运行以上命令会生成两个文件Client.cs 和 app.config。将这两个文件添加到客户端项目中即可。
(2)使用WCF客户端调用服务
通过以上两种方法产生的代理类,我们就很轻松地就像使用本地方法一样地调用WCF服务方法了,这一点基本上和调用Web Service 相同。
ServiceReference1.Service1Client wcfClient = new WCFClientApp.ServiceReference1.Service1Client();