WCF 笔记
2008-04-05 13:16 Animax! 阅读(1232) 评论(1) 编辑 收藏 举报WCF 笔记 – 简单使用:
WCF 概念:
WCF 是 “Windows Communication Foundation ”的缩写,Windows Communication Foundation (WCF) 是一个运行库和一组 API,用于创建在服务与客户端之间发送消息的系统。 它使用相同的基础结构和 API 来创建应用程序,这些应用程序可与同一计算机系统上或驻留在另一家公司内并通过 Internet 访问的系统上的其他应用程序进行通信。
WCF 通过一种面向服务的新型编程模型简化了关联应用程序的开发。通过提供分层的体系结构,WCF 支持多种风格的分布式应用程序开发。 WCF 通道体系结构在底层提供了异步的非类型化消息传递基元。
WCF体系结构图:
Contract(契约) :
在WCF中所有需要向外部服务的方法或对象都需要标明契约属性。
基本契约有4种:
服务契约(Service Contract) :
指示接口或类在 Windows Communication Foundation (WCF) 应用程序中定义服务协定。
数据契约(Data Contract) :
指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。若要使其类型可序列化,类型作者必须为其类型定义数据协定。
异常契约(Fault Contract):
指定服务操作遇到处理错误时返回的一个或多个 SOAP 错误
消息契约(Message Contract):
定义与 SOAP 消息相对应的强类型类。
简单WCFService创建:
WCF服务端:
这里创建一个最简单,以Web形式发布的WCFService,现在这里创建一个“WCF 服务应用程序”名为 “WebWcfServiceA”。
项目需要 System.ServiceModel 与 System.Runtime.Serialization 的引用。基本上所有有关于WCF的项目,都会需要到引用这两个组件。
此项目中有一个接口 IWebWcfServiceA 用于表示WCF公开的方法。
[ServiceContract]
public interface IWebWcfServiceA
{
[OperationContract]
string serviceFunction(int value);
}
这里接口中的契约属性ServiceContract 用于标明这个接口是公开可调用的。
方法中的契约属性 OperationContract 用于标明这个方法是公开可调用的。
除了接口外,还需要一个WCF服务文件 ,在这里命名为“WebWcfServiceA.svc”。
public class WebWcfServiceA : IWebWcfServiceA
{
public string serviceFunction(int value)
{
return string.Format("You entered: {0}", value);
}
}
这个类是WCF的主体,它继承于WCF公开的接口并完成接口的功能。
这里需要注意的是,所有对接口ServiceContract 和服务文件 WebWcfServiceA.svc进行过名称更改的,都需要在配置文件中进行相应的更改。
在配置文件中的 <system.serviceModel>节里面说明了WCF相关的配置,在这里需要注意的是元素service 和 endpoint 。 service 的 name 属性指名了WCF 服务类的位置;endpoint 的contract 属性指名了契约接口的位置。
客户端:
现在为这个简单的WCFService创建一个简单的客户端,控制台程序“WebWcfAClient”。
最简单创建客户端的办法就是像创建Web Service那样添加一个服务引用,这个服务引用直接指向刚才创建的WebWcfServiceA项目。
创建成功后,项目会添加一份app.config,此文件记录了关于WCF服务的信息,其中这里需要注意一下的是client 中的 endpointaddress ,这里记录了指向WCF 服务的路径。
创建这样一个服务引用后,便可以直接调用其中暴露出来的方法。
static void Main()
{
WebWcfServiceA.WebWcfServiceAClient ServiceA = new WebWcfAClient.WebWcfServiceA.WebWcfServiceAClient();
Console.WriteLine(ServiceA.serviceFunction(0));
Console.ReadKey();
ServiceA.Close();
}
这种客户端方式的调用,基本和webService的调用相似。
第二种WcfService创建:
因为公开暴露的方法是在接口上,所以除了使用服务引用的办法来创建客户端引用外,还可以通过使用引用该接口的办法来调用WCF的服务。
契约接口:
首先,创建一个接口项目(IWebWcfServiceB)用于服务端和客户端双方的调用:
[ServiceContract]
public interface IService
{
[OperationContract]
CompositeType serviceFunction(int value);
}
[DataContract]
public class CompositeType
{
[DataMember]
public string strValue
{
get;
set;
}
}
这里的CompositeType类的属性DataContract(数据契约)用于标明此类是用在于WCF服务中提供数据的,并且此类是可以序列化的。
属性strValue上的DataMember属性标明属性strValue可以序列化。
服务端:
服务段只有一个文件WebWcfServiceB.svc ,
public class WebWcfServiceB : IService
{
public CompositeType serviceFunction(int value)
{
CompositeType ct = new CompositeType();
ct.strValue = string.Format("You entered: {0}", value);
return ct;
}
}
它基本和WebWcfServiceB.svc一致,只是继承的接口被分离到另外一个项目中。
客户端:
客户端需要引用接口IWebWcfServiceB,还需要为接口创建一个代理类,用于调用WCF服务。
这个接口类可以手工创建,但是你运行打开上述的WebWcfServiceB.svc 文件时候会发现VS提供了一个工具svcutil.exe 来创建这个代理类。
这里是一个手工写的代理类:
public partial class ServiceClient : System.ServiceModel.ClientBase<IService>, IService
{
public ServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public CompositeType serviceFunction(int value)
{
return base.Channel.serviceFunction(value);
}
}
[DataContractAttribute]
public partial class CompositeType : object, System.Runtime.Serialization.IExtensibleDataObject
{
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get;
set;
}
[DataMemberAttribute]
public string strValue
{
get;
set;
}
}
需要注意的是这里的命名空间要和公开接口的命名空间一致。
如果使用工具写出的代码会有更多的实现方法,并且工具将会输出一个名为output.config 的文件,此文件和使用服务引用时添加的配置文件一样。
代理类的使用如下:
System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding();
System.ServiceModel.EndpointAddress address =
new System.ServiceModel.EndpointAddress(new Uri("http://localhost/WebWcfServiceB.svc"));
ServiceClient ServiceB = new ServiceClient(binding, address);
CompositeType ct = ServiceB.serviceFunction(0);
Console.WriteLine(ct.strValue);
Console.ReadKey();
ServiceB.Close();
如果是使用配置文件的,可以直接ServiceClient ServiceB = new ServiceClient() 来读取调用配置文件中的路径。
WCF服务库:
除了使用上面两种以WCF服务文件为主体,依附IIS的创建方式以外,还可以使用WCF服务库来创建WCF服务。
直接创建一个WCF服务库,可以看见IDE为你创建了三份文件,一个公开契约的接口,一个控制台应用程序的WCF服务主体,和一份配置文件。
这个结构和之前创建WCF 服务应用程序基本相同,只不过是主体由svc服务文件变为了控制台的应用程序。
服务端:
项目名称:HostWcfServiceA。
[ServiceContract]
public interface IService
{
[OperationContract]
string serviceFunction(int value);
}
public class HostWcfServiceA : IService
{
public string serviceFunction(int value)
{
return string.Format("You entered: {0}", value);
}
}
此服务运行后将会根据配置文件中baseAddress属性的地址来监听,该地址只是用于通信,不能使用浏览器打开。
客户端:
创建一个新的控制台程序HostWcfAClient 来作为客户端,客户端对此WCF服务的调用也可以使用服务引用,具体调用和WCF服务文件的方式一样。
服务端除了使用配置文件来配置监听路径外,还可以使用代码来配置监听路径,方法是使用另外一个应用程序来作为服务主机,让客户端调用。
服务端B:
此服务端B的服务库与项目HostWcfServiceA 的服务库一样,添加多一个控制台应用程序作为服务器:
Uri baseAddress = new Uri("http://127.0.0.1:55555");
using (ServiceHost host = new ServiceHost(typeof(HostWcfServiceB.HostWcfServiceB), new Uri[] { baseAddress }))
{
BasicHttpBinding binding = new BasicHttpBinding();
host.AddServiceEndpoint(typeof(HostWcfServiceB.IService), binding, baseAddress);
host.Open();
Console.WriteLine("服务已启动");
Console.Read();
}
最后声明: 此文只是本人学习WCF中的一点笔记,如有错谬,请指正。
本文源代码下载