在配置文件中,根节是<configuration>,所有的配置元素都位于其中。对于WCF服务的配置部分,最外层的节是<system.serviceModel>,所以配置文件中至少先应该是这个样子:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.       
  5.   </system.serviceModel>  
  6. </configuration>  


现在我们准备开始配置一个服务,服务配置元素标签为<services></services>,是<system.serviceModel>的子节,在一个宿主上可以承载许多服务,每一个服务用<service></service>来配置,它是<services>的子节。在配置<service>前,我们还要先添加一个基地址配置,基地址用<baseaddress>描述,他是<host>的子节,<host>是<service>的子节。

晕了么...慢慢来。

先把<services>节加上,这里可以容纳许多服务,注意这个是带s的

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.         
  6.     </services>      
  7.   </system.serviceModel>  
  8. </configuration>  


在<services>的怀抱中,我们添加一个<service>,这是我们要配置的服务本体,注意这个是不带s的

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service>  
  6.           
  7.       </service>  
  8.     </services>      
  9.   </system.serviceModel>  
  10. </configuration>  


在<service>中,添加一个基地址,先添加一个<host>再添加一个<baseaddress>

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service>  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.       </service>  
  12.     </services>      
  13.   </system.serviceModel>  
  14. </configuration>  

 

到这里,基地址的部分已经完成,对应代码中的位置你找到了么?

服务的配置还差一点,我们在代码中为服务指定了实现类型,在配置文件中如何指定呢?就用<service>标签的name属性,指定的时候后要用完全限定名(带着命名空间)

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service name="HelloWCFService.HelloWCFService">  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.       </service>  
  12.     </services>      
  13.   </system.serviceModel>  
  14. </configuration>  

我这个例子举的不好了,命名空间和实现类型是一个名字,要注意区分。

 

到这里,服务也配置完了,对应代码的位置翻上去找一下。

接下来配置终结点,终结点用<endpoint>元素表示,正如代码实现中的参数,在配置中也需要一一指定地址、绑定和服务协定接口,分别用address、binding和contract属性来表示,当然<endpoint>也是<service>的子节,毕竟他是属于服务的嘛。

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service name="HelloWCFService.HelloWCFService">  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.         <endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" />  
  12.       </service>  
  13.     </services>      
  14.   </system.serviceModel>  
  15. </configuration>  

这里用了相对地址"HelloWCFService",他会和基地址组合在一起(排在后面)成为终结点的地址,这里也可以指定为空字符串"",此时基地址(即服务地址)就是终结点的地址,还可以指定一个绝对地址,那样他会覆盖基地址,基地址对这个终结点来说就不起作用了,这里可以看出,终结点的地址是独立的,可以是基地址的子地址,也可以独立使用另一个地址,他们之间没有必然的链接。

这里的contract 同<service>里面一样,也要使用完全限定名称(带上命名空间)。

注意,在使用IIS承载的时候,必须使用相对地址,也就是终结点必须是基地址的子地址,这是由IIS的部署结构决定的。

 

到这里终结点也配置完成,对应代码的位置找到了吗?

 

接下来是最后一步(或者说两步),配置元数据交换终结点并开启元数据交换行为。这个过程,代码中用了三行,实际上代码这三行仅仅是添加了元数据交换行为,并没有配置元数据交换终结点,运行时系统为我们自动添加了终结点。这两点缺一不可,虽然系统会为我们添加,我们还是要知道这个配置的写法。这个很重要。

 

开启元数据交换从原理上应该是两件事,第一是服务允许元数据交换,第二是服务提供元数据交换方式,第一条就是添加元数据交换行为,表示服务允许这样的请求,第二条就是服务告诉你如何请求,客户端是通过一个固定的终结点去请求的,这个终结点的地址、绑定和协定都是固定的,我们不能更改,这个是框架的约定,我们只能按要求配置。

 

首先,第一条,允许元数据交换,这个是通过为服务添加一个行为来实现的,行为是用来描述服务的特性的,不同的服务可能有相同的行为,行为并不是归某服务独有的,因此行为被定义为<system.serviceModel>节的子节,可以被不同的服务引用,他的定义有些像服务,外面是带s的,里面是不带s的,毕竟可能有许多的行为定义嘛。

先定义个行为:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service name="HelloWCFService.HelloWCFService">  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.         <endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" />  
  12.       </service>  
  13.     </services>  
  14.     <behaviors>  
  15.       <serviceBehaviors>  
  16.         <behavior name="metaExchange">  
  17.           <serviceMetadata httpGetEnabled="true"/>  
  18.         </behavior>  
  19.       </serviceBehaviors>  
  20.     </behaviors>  
  21.   </system.serviceModel>  
  22. </configuration>  

因为存在服务行为和终结点行为之分,所有<behaviors>和<behavior>之间又套了一个<serviceBehaviors>,表示这个是服务行为,我们为行为制定了名字,好让<service>可以引用,也可以不指定,那么所有服务都会应用。交换元数据的行为有固定的标签描述,就是<serviceMetadata>,对着代码看,很熟悉吧。

 

建立了行为以后,要让我们刚才建立的服务去引用他,用<service>的behaviorConfiguration属性:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service name="HelloWCFService.HelloWCFService"behaviorConfiguration="metaExchange">  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.         <endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" />  
  12.       </service>  
  13.     </services>  
  14.     <behaviors>  
  15.       <serviceBehaviors>  
  16.         <behavior name="metaExchange">  
  17.           <serviceMetadata httpGetEnabled="true"/>  
  18.         </behavior>  
  19.       </serviceBehaviors>  
  20.     </behaviors>  
  21.   </system.serviceModel>  
  22. </configuration>  

 

接下来第二步,建立元数据交换终结点,建立的位置和我们刚才建立的终结点位置相同,但是属性是固定的,大小写都不能写错。

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <service name="HelloWCFService.HelloWCFService" behaviorConfiguration="metaExchange">  
  6.         <host>  
  7.           <baseAddresses>  
  8.             <add baseAddress="http://localhost:8000/MyService"/>  
  9.           </baseAddresses>  
  10.         </host>  
  11.         <endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" />  
  12.         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>  
  13.       </service>  
  14.     </services>  
  15.     <behaviors>  
  16.       <serviceBehaviors>  
  17.         <behavior name="metaExchange">  
  18.           <serviceMetadata httpGetEnabled="true"/>  
  19.         </behavior>  
  20.       </serviceBehaviors>  
  21.     </behaviors>  
  22.   </system.serviceModel>  
  23. </configuration>  


到这里,配置文件就写完了。