首先简单介绍一下 WCF 是什么,然后再对 WCF 和 Asp.net Web service 做个比较。

    Windows Communication Foundation (WCF) 是用于构建面向服务的应用程序的框架。借助 WCF,可以将数据作为异步消息从一个服务终结点发送至另一个服务终结点。服务终结点可以是由 IIS 承载的持续可用的服务的一部分,也可以是应用程序中承载的服务。终结点可以是从服务终结点请求数据的服务客户端。消息可以是从以 XML 格式发送的单个字符或单词,到复杂的二进制数据流。虽然在WCF 出现之前也可以开发应用,但是 WCF 的出现使此类应用的开发变得更加简单。

 

    Asp.net Web service 通常依赖于 XmlSerializer 将 .NET Framework 的数据类型转换为 XML 格式在服务中传送,或将从服务中接收的 XML 格式的数据转换为 .NET Framework 中的对象。

使用 XmlSerializer 序列化或反序列化 .NET Framework 的数据类型时的缺点:

1、只有标记为 public 的字段和属性能够被序列化。

2、只有实现了 IEnumerableICollection 接口的类的集合才能被序列化。

3、实现 IDictionary 接口的类不能被序列化,如Hashtable。

    WCF 使用 DataContractAttributeDataMemberAttribute 来标记可以被序列化的 .NET Framework 类型。

[DataContract]
public class Item
{
    [DataMember]
    public string ID;
    [DataMember]
    public decimal Qty;
    [DataMember]
    public decimal Price;
}

DataContractAttribute 可以应用于类或结构体上,DataMemberAttribute可以应用于标记为 public 或 private 的字段和属性上。

DataContractSerializer 和 XmlSerializer的区别:

1、DataContractSerializer 不对 .NET Framework 中的数据类型在 XML 中的表示方式作控制,因此性能要比 XmlSerializer 高。

2、XmlSerializer 不能确定要序列化的字段或属性,而 DataContractSerializer 使用 DataMemberAttribute 可以明确的确定要序列化的字段或属性。

3、DataContractSerializer 可以序列化实现了 IDictionary 接口的类。

4、由于 DataContractSerializer 可以访问对象的非 public 成员,因此在反序列化时需要运行在完全信任模式下,而 XmlSerializer 不需要。

 

服务的开发

在开发 Asp.net Web service 时需要在类上面添加 WebService 属性(attribute),在类的方法上添加 WebMethodAttribute

[WebService]
public class WebService1 : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

一个 WCF 服务提供一个或多个 WCF 终结点(Endpoint),每个终结点包含地址(Address)、绑定(Binding)、契约(Contract)。开发 WCF 服务时,通常先在接口上添加 ServiceContractAttribute 和 OperationContractAttribute 来定义服务的契约(contract):

[ServiceContract]
public interface IService1
{
    [OperationContract]
    void DoWork();
}

ServiceContractAttribute 指定接口定义了一个 WCF 服务契约,OperationContractAttribute 表示接口中的哪个方法定义为服务契约中的操作。定义好服务契约后需要一个类来实现它:

public class Service1 : IService1
{
    public void DoWork()
    {
        // do some works
    }
}

实现了服务契约的类即是 WCF 中的一个服务。接下来在配置文件中配置服务地址和绑定类型

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
     <system.serviceModel>
      <services>
      <service name="Service1">
       <endpoint 
        address="Service1"
        binding="basicHttpBinding"
        contract="IService1"/>
      </service>
      </services>
     </system.serviceModel>
</configuration>

绑定指定了如何与终结点进行通信。WCF 支持的绑定有

BasicHttpBinding、WSHttpBinding、WSDualHttpBinding、WSFederationBinding、NetTcpBinding、NetNamedPipeBinding、NetMsmqBinding、MsmqIntegrationBinding、NetPeerTcpBinding。其中 BasicHttpBinding 包含了 Asp.net Web services 支持的协议。

 

服务的承载

Asp.net Web service 编译后生成一个程序集和一个扩展名为 .asmx 的服务文件,该文件中包含了服务类的代码和其所在的程序集的信息。将服务文件复制到由 IIS 承载的 Asp.net 程序的根目录下,将程序集复制到程序根目录下的 /bin 目录下。服务就可以通过服务文件的 URL来访问了。

WCF 服务可以由 IIS、Windows Process Activation Service(WAS)或 .NET 应用程序承载。在IIS或WAS中承载的步骤:

1、编译服务。

2、将扩展名为 .svc 的服务文件复制到一个虚拟目录下,将程序集复制到虚拟目录下的 /bin 文件夹下。

3、将web.config配置文件复制到虚拟目录下。

 

客户端开发

Asp.net Web service 客户端通过命令行工具 WSDL.EXE 生成客户端代码。

WCF 使用ServiceModel Metadata Utility Tool(svcutil.exe)生成客户端代码。

 

消息协定

Asp.net Web service 中的 SOAP 消息的消息头是可以自定义的。

WCF 通过 MessageContractAttribute、MessageHeaderAttribute和MessageBodyMemberAttribute 来描述服务中的 SOAP 消息的结构。

 

元数据

客户端通过 HTTP GET 向 Asp.net Web service 请求元数据时,ASP.NET 将生成 WSDL 并发送到客户端。生成的 WSDL 可以通过创建一个继承自 ServiceDescriptionFormatExtension 的类来自定义。

客户端可以向 WCF 发送由 WS-MetadataExchange 标准定义的请求信息,接收返回的 WSDL。WCF 生成的 WSDL 也可以自定义。WCF 还可以配置为不生成 WSDL,并提供一个固定的 WSDL 文件的URL。

 

异常处理

在 Asp.net Web service 中未处理的异常会作为 SOAP 错误返回客户端。

在 WCF 服务中未处理的异常不会作为 SOAP 错误返回客户端。在调试时可以通过配置设置让未处理的异常返回客户端。

 

安全

Asp.net Web services 安全设置和其他IIS 应用的安全设置相同。

WCF 可以承载于 IIS 之外的其他应用程序中,因此 WCF 的安全设置是独立的。但是可应用于Asp.net Web service 的安全设置也可应用于 WCF。