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具体对应什么。

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-17 12:49:41

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

[老老实实学WCF] 第三篇 在IIS中寄存服务

原文:[老老实实学WCF] 第三篇 在IIS中寄存服务 老老实实学WCF 第三篇 在IIS中寄宿服务   通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我们对WCF的编程生命周期有了一个最基本的了解.   在前两篇中演示的例子,一定要力求背着做下来,包括源程序.配置文件都要背着一行行的手写下来,这样才能有深刻的体会.WCF的知识零散复杂,必须扎扎实实的学习和练习.如果你还没有做到了然于胸,现

十五天精通WCF——第三天 client如何知道server提供的功能清单

原文:十五天精通WCF--第三天 client如何知道server提供的功能清单  通常我们去大保健的时候,都会找姑娘问一下这里能提供什么服务,什么价格,这时候可能姑娘会跟你口述一些服务或者提供一份服务清单,这样的话大 家就可以做到童嫂无欺,这样一份活生生的例子,在wcf中同样是一个道理,只有client了解service能提供哪些功能,client才可以根据server提供的功能进行 消费,那问题来了,service怎么把功能提供给client进行选择呢???这个就是我这一篇要聊的wsdl(w

[WCF权限控制]WCF的三种授权模式

前面的两篇文章(<从两个重要的概念谈起:Identity与Principal[上篇]>和<从两个重要的概念谈起:Identity与Principal[下篇]>)主要探讨基于安全主体的授权.通过这些介绍我们知道:如果我们在实施授权的时候,当前线程的安全主体能够被正确设置,我们就可以正确地完成授权.基于相同的原理,对于WCF的服务授权,如果正确的安全主体能够在服务操作被执行之前被正确设置到当前线程,借助于这个安全主体,我们不但可以采用命令式编程的方式将授权逻辑写在相应的操作中,也可以采

WCF学习(三):数据契约1

WCF能够托管CLR类型,客户端能传递和处理CLR类型的数据(如:string和int),但是如果我们自己定义的类型(如:声明的Customer类).其实WCF的传递CLR自己类型时,是因为已经把它序列化成了xml信息集,而我们自己定义的类型则需要自己去显示的声明序列化. 序列化 .net的序列化..net是通过反射机制(反射机制参考文档)自动实现对象的序列化与反序列化.首先.net能够捕获对象每个字段的值,然后进行序列化,反序列化时,.net创建一个对应类型的新的对象,读取持久化的值,然后设置

谁知道这个控件的名称和事件.方法,立即给分

问题描述 当多个TABPAGE放在TABCONTROL上时,通过设置MULTILINE可以选择是否TABPAGE全显示,或者通过一个左右箭头的控件来移动TABPAGE.谁知道这个左右箭头叫什么名称,当点击时调用什么事件呢? 解决方案 解决方案二:Tabpagetabcontrolmultitine是嘛玩意,在VS2008有么?解决方案三:左右箭头的事件微软封装在内部了解决方案四:LSD有什么方法调用吗解决方案五:这个应该是自动产生的吧,不需要人为的干预,就像你的scorllbar一样,auto模

PHP中的命名空间详细介绍

  这篇文章主要介绍了PHP中的命名空间详细介绍,本文讲解了命名空间(namespace)的概念.正在使用命名空间.定义命名空间.子命名空间.从命名空间中调用代码等内容,需要的朋友可以参考下 概述 PHP对于命名空间的支持,经历了一段艰难的旅程.幸运的是,PHP从5.3开始引入了命名空间.自从PHP引入了命名空间,PHP代码的适用结构也得到了大大的改善.许多编程语言早就有了命名空间的概念,相对于其他语言来说,PHP对于命名空间的支持,稍微有点晚了.不管如何,每一种新特性的引入都有其目的,和其他语

PHP中的命名空间详细介绍_php技巧

概述 PHP对于命名空间的支持,经历了一段艰难的旅程.幸运的是,PHP从5.3开始引入了命名空间.自从PHP引入了命名空间,PHP代码的适用结构也得到了大大的改善.许多编程语言早就有了命名空间的概念,相对于其他语言来说,PHP对于命名空间的支持,稍微有点晚了.不管如何,每一种新特性的引入都有其目的,和其他语言一样,PHP引入命名空间也主要是为了解决名字冲突的问题. 命名空间(namespace)的概念 复制代码 代码如下: 当在字符串中使用命名空间名字的时候,一定不要忘了转义\ 可以将命名空间想

PHP命名空间(Namespace)的使用详解

对于命名空间,官方文档已经说得很详细[查看],我在这里做了一下实践和总结. 命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误.这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀. 例:项目中有两个模块:article和message board,它们各自有一个处理用户留言的类Comment.之后我可能想要增加对所有用户留言的一些信息统计功能,比如说我想得到所有留言的数量.这时候调用它们Comment提供的方法是很好的

[WCF 4.0新特性] 路由服务[原理篇]

在一个典型的服务调用场景中,具有两个基本的角色,即服务的消费者和服务的提供者.从消息交换的角度讲前者一般是消息的最初发送者,而后者则是消息的最终接收者.在很多情况下,由于网络环境的局限,消息的最初发送者和最终接收者不能直接进行消息交换,这就需要一个辅助实现消息路由的中介服务,这就是我们接下来要介绍的路由服务. 目录 一.路由服务就是一个WCF服务       路由服务契约的定义       路由服务契约的定义 二.基于消息内容的路由策略       RoutingBehavior服务行为