WCF 根据服务端源代码中定义的内部类名称和属性来生成外部暴露服务实现。这些实现通过服务中的MEX终结点暴露出来并在设计阶段时被客户端以WSDL形式使 用。接下来在客户端,WSDL会被用来写一些代码来建立可以与服务端通信的适当的消息格式。所以你选择的类,方法和参数的名字与服务范围潜在相差很远。
然而,在服务的接口暴露内部名字和外部细节是很不好的形式。比如,你可能有一个叫BurgerMaster的分配算法,你想在外部以 Resources名字暴露这个算法。或者可能有内部的编码标准要求你应该命名接口。幸运的是,你可以通过修改[ServiceContract], [OperationContract], [ServiceBehavior]来控制所有服务暴露的名字。表2.3列出了如何在代码中使用WCF属性来控制WSDL条款。
表2.3 重载默认WSDL名字的WCF属性
列表2.13中定义的服务使用WCF属性来重载WCF生成的默认名字。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Service
{
[ServiceBehavior(Namespace="http://MyService/")]
[ServiceContract(Name="MyServiceName",Namespace="http://ServiceNamespace")]
public class BurgerMaster
{
[return: MessageParameter(Name = "myOutput")]
[OperationContract(Name = "OperationName",Action = "OperationAction",ReplyAction = "ReplyActionName")]
public double GetStockPrice(string ticker)
{
return 100.00;
}
}
}
svcutil.exe 实例加上-t:metadata 开关可以用来从一个服务生成WSDL。相应的,如果服务通过一个http绑定来暴露一个MEX终结点,WSDL可以在IE通过访问基地址来查看。WSDL 的格式在svcutil.exe或者IE查看时会有些轻微的不同,但是这些不同是不重要的,因为它们仅仅是涉及打包方面的。在任何一种情况 下,wsdl:portType, wsdl:operation和wsdl:action名称由代码控制。注意wsdl:portType名字是MyServiceName而不是 BurgerMaster,与列表2.13中的类名称一样。
列表2.14 通过控制名字来列出WSDL
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap=http://schemas.xmlsoap.org/wsdl/soap/xmlns:wsu="http://docs.oasis-open.org/wss/2004/xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding/xmlns:tns=http://ServiceNamespacexmlns:xsd=http://www.w3.org/2001/XMLSchemaxmlns:wsaw=http://www.w3.org/2006/05/addressing/wsdlxmlns:soap12=http://schemas.xmlsoap.org/wsdl/soap12/xmlns:wsa10="http://www.w3.org/2005/08/addressing" xtargetNamespace=http://ServiceNamespacexmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema targetNamespace="http://ServiceNamespace/Imports">
<xsd:import namespace="http://ServiceNamespace" />
<xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="MyServiceName_OperationName_InputMessage">
<wsdl:part name="parameters" element="tns:OperationName" />
</wsdl:message>
<wsdl:message name="MyServiceName_OperationName_OutputMessage">
<wsdl:part name="parameters" element="tns:OperationNameResponse" />
</wsdl:message>
<wsdl:portType name="MyServiceName">
<wsdl:operation name="OperationName">
<wsdl:input wsaw:Action="OperationAction"message="tns:MyServiceName_OperationName_InputMessage" />
<wsdl:output wsaw:Action="ReplyActionName"message="tns:MyServiceName_OperationName_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DefaultBinding_MyServiceName" type="tns:MyServiceName">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="OperationName">
<soap:operation soapAction="OperationAction"style="document"mce_style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>