可能大家会觉得我说完了wcf的介绍以后,会介绍wcf的契约、服务这些内容,但是我没有,为什么呢?原因就是我一直坚持的从程序员中来,到程序员中去的观点。程序员的学习是一个渐进的过程,不是有了介绍就可以直接了解wcf的全貌,但是我也没有介绍wcf的配置,因为这个内容很多,但是我今天要介绍的是wcf中的一个知识点,这个知识点只是一个渐进的过程,但是知道了这个知识点以后,我们可以避免很多错误的发生。所以我说一下wcf中的一个Attribute ConfigurationName。
在很多的契约及其服务行为属性中我们都可以看到这个属性的存在,但是这个属性究竟是做什么的。如果不仔细看一下很真是有些误导,但是一旦明白了,心理就会大呼一口气,那么简单,会则不难的道理。呵呵。
废话少说,因为configurationName的属性在ServiceContract以及ServiceBehavior中都是一样的。所以我就通过ServiceContract来说明一下。
还是上一次做的项目,我们在契约ServiceContract中添加ConfigurationName的值。有一点我们需要注意一下,如果我们不指定这个属性的值,那么这个属性的默认值就是这个接口或者类所在的命名空间全称。不太好理解,上代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 namespace Chinaer.WcfDemo.Contracts 7 { 8 [ServiceContract(Name = "ICal", Namespace = "http://www.chinaer.com",ConfigurationName="ICalInterface")] 9 public interface ICal 10 { 11 [OperationContract] 12 int Add(int x, int y); 13 14 int Sub(int x, int y); 15 } 16 }
大家请注意,我添加了ConfigurationName属性的值为ICalInterface。因为原来的项目是可以运行的,那么如果我现在运行这个项目会出现什么样的结果呢?我i启动的是控制台宿主程序。
出现了异常,提示找不到协定名称。但是我们仔细看一下,服务名称为CalService,找不到协定名称,这个异常让我们摸不到头脑。因为wcf的异常信息有时候确实令人懊恼。但是现在我们知道了目标,就是configurationName属性的设定。这也是我们以后遇到此类异常信息可以查找的一个问题所在。现在我们来更改一下控制台宿主程序的配置文件。让ConfigurationName的值设定在配置文件中。上代码
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <system.serviceModel> 4 <services> 5 <service name="Chinaer.WcfDemo.Services.CalService" behaviorConfiguration="metaDataBehavior"> 6 <endpoint address="http://127.0.0.1:8888/calservice" binding="wsHttpBinding" contract="ICalInterface"></endpoint> 7 </service> 8 </services> 9 <behaviors> 10 <serviceBehaviors> 11 <behavior name="metaDataBehavior"> 12 <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8888/calservice/metadata"/> 13 </behavior> 14 </serviceBehaviors> 15 </behaviors> 16 <bindings> 17 </bindings> 18 </system.serviceModel> 19 </configuration>
配置文件没有什么好说的,就是那个endpoint节点的contract的设定值,我们更改成了ICalInterface,就是刚才我们设定的ConfigurationName的值。在此运行控制台宿主程序,就会运行正常。
还有一个需要我们注意的地方就是,我们尽量不要手动输入,因为wcf配置文件是大小写敏感的,如果我们输入错误,那么提示的异常信息和我们刚才的一样。
上面都是说configurationName给我们带来的不便,那肯定有好处了,要不微软也不会添加这么一个属性了。我个人认为这个属性的添加可以让我们从拼写完整的命名空间全称中解脱出来。举个简单的例子,如果我们不设定ConfigurationName的值,那么我们在endpoint节点的contract的值就应该为WcfDemo.Contracts.ICal.因为这个属于字符串的输入,没有智能提示,所以我们输入错误的风险很高,如果我们采用了ConfigurationName的话,那么我们要输入的内容就会减少很多。这么说吧,凡是需要用到全名称的地方,我们都可以用这个ConfigurationName的值来代替。
当然我在这里有个建议,就是在开始开发的时候尽量不要定义ConfigurationName的值,等到以后项目上线的时候再修改,因为定义了这个值的话,别人做模块的话还需要告知他们,不如上线的时候统一一个文档,统一更改来的舒服。当然这只是我的个人建议。
在ServiceBehavior中也有一个ConfigurationName的属性值,和这个ServiceContract的属性作用相同,我就不赘述了。
其实知道了ConfigurationName的作用以后,感觉就是那么的简单。呵呵,加油各位
我又回来了,回到了技术最前线,