WCF的三个名称/命名空间,你是否傻傻分不清楚?

在定义和寄宿WCF服务的时候会面临三个名称/命名空间,它们分别是ServiceContractAttribute、ServiceBehaviorAttribute和Binding的Name和Namespace属性,很对人对此不能很好地区分。

一、ServiceContractAttribute的名称/命名空间

每个服务契约都有一个确定的名称,当在一个接口或类上应用了ServiceContractAttribute特性,默认的名称就是接口或类的名称。我们可以通过Name属性显式地指定需要的名称,这在某些场景中往往具有重要的作用。比如在客户端有一个通过接口的形式定义的服务契约,现有的很多客户端代码均依赖于这个接口,如果这个时候服务方的名称改变了,客户端仅须更新这个Name属性,从而避免修改接口的名称而造成对现有代码的影响。

   1: public sealed class ServiceContractAttribute : Attribute
   2: {   
   3:     //其他成员    
   4:     public string Name { get; set; }
   5:     public string Namespace { get; set; }
   6: }

至于服务契约的命名空间,其作用和我们托管语言(比如C#、VB.NET)的命名空间完全一样,旨在解决命名冲突问题。很多WCF的编程人员都不太注重在定义服务契约的时候指定命名空间,这是一个不太好的习惯。我们鼓励采用包含你所在的公司名称或项目名称作为命名空间。WCF默认采用的命名空间是http://tempuri.org/

作为服务的描述信息,服务契约作为WSDL的一部分以元数据的形式发布出来。WSDL通过<portType>元素定义相应的服务契约。ServiceContractAttribute的Name和Namespace属性对应着用于描述服务契约的<portType>元素的名称和命名空间。

   1: [ServiceContract(Name = "CaclService", Namespace = "http://www.artech.com/")]
   2: public interface ICalculator
   3: {
   4:     //省略成员
   5: }

如上面的代码所示,我们应用了ServiceContractAttribute特性将接口ICalculator接口定义成服务契约。ServiceContractAttribute的Name和Namespace分别被设置成CaclService和http://www.artech.com/"。服务契约将会对应着如下一段WSDL。

   1: <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
   2:                   xmlns: tns = "http://www.artech.com/"...>
   3:    <wsdl:portType name="tns:CaclService">
   4:      ...
   5:   </wsdl:portType>
   6: </wsdl:definitions>

二、ServiceBehaviorAttribute的名称和命名空间

关于通过ServiceContractAttribute特性定义的服务契约的名称和命名空间,很多人会和通过ServiceBehaviorAttribute定义的名称和命名空间混淆。

   1: [AttributeUsage(AttributeTargets.Class)]
   2: public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
   3: {
   4:     //其他成员
   5:     public string Name { get; set; }
   6:     public string Namespace { get; set; }
   7: }

实际上服务行为特性ServiceBehaviorAttribute定义的是服务本身的名称和命名控件。这两个属性将作为整个WSDL根节点< definitions >的name和targetNamespace属性。如果没有对其进行显式设置,默认的命名空间为http://tempuri.org/。WCF将使用服务类型的名称作为作为服务名称。

   1: [ServiceBehavior(Name = "CaclService", 
   2:           Namespace ="http://www.artech.com")]
   3: public class CalculatorService : ICalculator
   4: {
   5:   //省略成员
   6: }

对于上面定义的服务类型来说,由于我们通过ServiceBehaviorAttribute特性对名称和命名空间进行了显式设置。用于描述服务的WSDL将具有如下一个根节点。

   1: <wsdl:definitions  name="CaclService" 
   2:                    targetNamespace="http://www.artech.com"
   3:                    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ...>
   4: </wsdl:definitions>

三、Binding的名称和命名空间

既然已经将到了服务契约和服务的名称和命名空间,我们顺便来谈谈另一组命名和命名空间。其实作为终结点三要素之一的绑定也具有自己的名称和命名空间。如下面的代码所示,作为绑定基类的抽象类Binding同样具有一组Name和Namespace属性。

   1: public abstract class Binding
   2: {
   3:     //省略成员
   4:     public string Name { get; set; }
   5:     public string Namespace { get; set; }
   6: }

Binding的名称和命名空间通过服务终结点的bindingName和bindingNamespace属性进行设置。由于这两个属性属于服务描述范畴,所以客户端终结点无此设置。由于绑定在WSDL中对应的节点为<binding>,所以绑定的Name和Namespace属性值将作为对应的<binding>节点的名称和命名空间。在默认的情况下,<binding>元素的命名空间的值依然是http://tempuri.org/。至于名称,则通过绑定类型名称和契约名称合并而成。比如说契约名称为ICalculator,并采用BasicHttpBinding,那么对应的<binding>元数的名称为BasicHttpBinding_ICalculator。

   1: <configuration>
   2:   <system.serviceModel>    
   3:     <services>
   4:       <service ...>
   5:         <endpoint bindingName="myBasicHttpBinding"
   6:                   bindingNamespace="http://www.artech.com" .../>
   7:       </service>
   8:     </services>
   9:   </system.serviceModel>
  10: </configuration>

比如说在服务寄宿时采用如上的配置将终结点的绑定名称和命名空间进行了显式设置,并且采用如上的服务契约(名称被定义成CalcService)。该终结点绑定在WSDL中将对应于如下一个<binding>元素。

   1: <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   2:                   xmlns:tns = "http://www.artech.com/">
   3:   <wsdl:binding name="tns: myBasicHttpBinding_CalcService" ...>    
   4:   </wsdl:binding>
   5: </wsdl:definitions>

总结

要区分上述三个名称/命名空间其实不然,只要我们知道终结点三要素在WSDL具体对应什么。

posted @ 2011-11-13 10:00 Artech 阅读(4026) 评论(13) 编辑 收藏

 回复 引用 查看   
#1楼 2011-11-13 11:41 幸运草      
沙发,顶
持续顶一下。
 回复 引用 查看   
#3楼 2011-11-14 10:56 开国伟人      
支持。下。
 回复 引用 查看   
#4楼 2011-11-17 22:07 love begins coding      
获益匪浅····如果结合WCF Service Configuration Editor来讲解这个东西,我想会让人更好的理解····
 回复 引用 查看   
#5楼 2011-11-18 14:14 凡玮      
支持。。。
 回复 引用 查看   
#6楼[楼主] 2011-11-18 16:32 Artech      
引用love begins coding:获益匪浅····如果结合WCF Service Configuration Editor来讲解这个东西,我想会让人更好的理解····

如果对WCF的配置结构不是很了解,我到反而不推荐使用WCF Service Configuration Editor,直接编辑配置可以更加深刻地了解WCF。

 回复 引用 查看   
#7楼 2011-11-18 22:53 love begins coding      
有道理,理解过程才是最重要···对了,您的WCF系列的书籍在哪里可以买到?现在想学习WCF方面的知识,您可以推荐些书籍么?
 回复 引用 查看   
#8楼 2011-11-18 22:54 love begins coding      
@Artech
有道理,理解过程才是最重要···对了,您的WCF系列的书籍在哪里可以买到?现在想学习WCF方面的知识,您可以推荐些书籍么?

不是很理解 要先保存下来
 回复 引用 查看   
#10楼 2011-11-30 17:03 james.dong      
拜读!
 回复 引用 查看   
#11楼[楼主] 2011-12-02 09:24 Artech      
引用love begins coding:
@Artech
有道理,理解过程才是最重要···对了,您的WCF系列的书籍在哪里可以买到?现在想学习WCF方面的知识,您可以推荐些书籍么?

我的书早就已经买不到了,等再版吧:)

 回复 引用 查看   
#12楼 2011-12-13 21:00 Ref Tian      
不错
 回复 引用 查看   
#13楼 2012-02-09 11:44 Virus-BeautyCode      
活用
[ServiceContract(Namespace="http://www.cnblogs.com/Product",Name="IProduct")]

还有很多好处的。

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 2247058 bsewuKV/wuo=