WCF配置文件详解

今天来看看WCF的配置方法。


上图整理了服务配置过程中所用到的基本的元素,大致的步骤主要是首先要在调用服务的程序集中添加服务的一个引用,然后添加一个service并指定服务的名称、终结点,如果添加了behavior(行为)的配置,那么也需要添加一个behaviorConfiguration的配置信息。在添加一个service时会在其中指定终结点的信息,终结点说的就是服务的具体信息访问方式,在终结点中添加服务address及binding信息和contract(服务契约)信息等。在endpoint中添加的binding只是指定了服务绑定的访问方式,例如:basicHttpBinding等,真正的binding配置是需要在另外的binding中添加的,添加好后需要配置在endpoint的bindingConfiguration。下面看一个服务在客户端部署配置的示例。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>

    <!--The bindings configuration  
We deployed the basichttpbinding.  
I added a binding that name is binding1.  
The binding1 used the security.  
-->
    <bindings>
      <basicHttpBinding>
        <binding name="binding1">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <!--The behaviors configuration  
I added a serviceBehavior that has nothing configuration in.  
-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="service1_behavior">

        </behavior>
      </serviceBehaviors>
    </behaviors>

    <!--The services configuration  
I added a service that behaviorConfiguration is service1_behavior.  
This service has an endpoint that added the property and the binding.  
-->
    <services>
      <service name="Wcfservice.Service1" behaviorConfiguration="service1_behavior">
        <endpoint address="http://localhost:64921/Service1.svc" name="ServiceReference1_IService1"
         binding="basicHttpBinding" bindingConfiguration="binding1" contract="ServiceReference1.IService1"></endpoint>
      </service>
    </services>

  </system.serviceModel>
</configuration>

上例将配置信息写入到了xml中,分别添加了一个服务的binding、service和behavior,在添加时往往是自下向上添加,首先添加一个binding配置信息,然后添加相应的behavior行为,最后添加一个service并把绑定信息添加到其中。

service

service主要是用来配置endpoint和host的,它实际上代表了为程序集添加了一个服务的引用,其中的endpoint指定了服务的地址、绑定和协议,host则提供了服务寄宿的方式。
如下配置:

<services>
  <service name="Wcfservice.Service1">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:64921/ConsoleApplication1"/>
      </baseAddresses>
    </host>
    <endpoint address="http://localhost:64921/WcfService1.IService1" binding="basicHttpBinding"
     bindingConfiguration="binding1" contract="ServiceReference1.IService1"></endpoint>
  </service>
</services>

在上面的代码中添加了一个service,并为service配置了一个host该host的应用程序即为当前引用服务的程序集。最后添加了一个endpoint,终结点中绑定了URI,URI的地址就是WCF的定义地址,其中的binding是指定了基本的绑定类型,另外还使用contract指定了服务契约的接口。

binding

service是对服务进行的配置,指定了服务的一些配置信息,另外很重要的和service同级还有binding,它是对消息访问方式做的一些配置。
1、绑定方式
分为系统自带的绑定和用户自定义绑定两种,系统自带的绑定包括basicHttpBinding、WcHttpBinding等。
如果系统提供的绑定功能不完全,那么也可以使用用户自定义的绑定功能,可以使用customBinding对象从预先存在的绑定元素中创建新的绑定,也可以通过从Binding派生类来创建完全由用户自定义的绑定。
2、基本功能
绑定除了定义绑定的方式外,还可以指定传输协议的类型、安全性、编码方式和事务等,通过绑定来配置WCF的基本操作类型,这样能够对服务做详细的一些配置,使服务的功能更加健全。

<?xml version=”1.0” encoding=”utf-8” ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name =”WCFService.ServiceClass” behaviorConfiguration=”metadataSupport”>
        <host>
          <baseAddresses>
            <add baseAddress=”net.pipe://localhost/WCFService”/>
            <add baseAddress=”net.tcp://localhost:8000/WCFService”/>
            <add baseAddress=”http://localhost:8080/WCFService”/>
          </baseAddresses>
        </host>
        <endpoint address=”tcpmex” binding=”mexTcpBinding”
         contract=”IMetadataExchange”/>
        <endpoint address=”namedpipemex” binding=”
mexNamedPipeBinding” contract=”IMetadataExchange”/>
        <endpoint address=”” binding=”wsHttpBinding”
        contract=”WCFService.IServiceClass”/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name=”metadataSupport”>
          <serviceMetadata httpGetEnabled=”false” httpGetUrl=””/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Behavior

行为属性,行为属性可以控制服务的运行时特性,主要分为服务行为和操作行为,这些行为或特性,可以通过配置runtime属性配置文件,或自定义行为来实现。

<?xml version=”1.0” encoding=”utf-8” ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name =”WCFService.ServiceClass” behaviorConfiguration=”metadataSupport”>
        <host>
          <baseAddresses>
            <add baseAddress=”net.pipe://localhost/WCFService”/>
            <add baseAddress=”net.tcp://localhost:8000/WCFService”/>
            <add baseAddress=”http://localhost:8080/WCFService”/>
          </baseAddresses>
        </host>
        <endpoint address=”tcpmex” binding=”mexTcpBinding” contract=”IMetadataExchange”/>
        <endpoint address=”namedpipemex” binding=”mexNamedPipeBinding” contract=”IMetadataExchange”/>
        <endpoint address=”” binding=”wsDualHttpBinding” contract=”WCFService.IServiceClass”/>
        <!--<endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange”/>-->
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name=”metadataSupport”>
          <!--允许客户端侦听服务器日志,在正式运行前最好关闭-->
          <serviceDebug includeExceptionDetailInFaults=”true”/>
          <serviceMetadata httpGetEnabled=”false” httpGetUrl=””/>
          <serviceThrottling maxConcurrentCalls=”10” maxConcurrentInstances=”5” maxConcurrentSessions=”5”/>
          <serviceSecurityAudit auditLogLocation=”Application” suppressAuditFailure=”false”/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Note:serviceMetadata 是一种元数据启用功能,它是配置元数据终结点,默认情况下是不公开元数据的,但是可以通过启用配置来公开元数据的终结点。
上面的代码都是使用的是配置文件做的服务的配置部署,另外也可在程序中编写代码来配置部署信息,但是并不赞成这种配置方式,因为这种配置方式不易更改,当你部署到客户环境后就不能再更改内部的代码结构,所以这种方式很不灵活,并不提倡使用这种方式来配置服务,但是可以作为了解,如下代码:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(ServiceReference1.Service1Client)))
            {
                host.AddServiceEndpoint(typeof(ServiceReference1.IService1),
                new WSHttpBinding(), "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1");
                if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                {
                    ServiceMetadataBehavior serviceMetadata = new ServiceMetadataBehavior();
                    serviceMetadata.HttpGetEnabled = true;
                    serviceMetadata.HttpGetUrl = new Uri
                    ("http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/metadata");
                    host.Description.Behaviors.Add(serviceMetadata);
                }

                host.Open();

                ServiceReference1.IService1 service1 = new ServiceReference1.Service1Client();
                service1.GetData(1);
                Console.Write("fdsf");
                host.Close();
            }
        }
    }
}

上面的代码中使用的是WSHttpBinding方式它支持双工通信,另外上面的宿主方式使用的是ConsoleApplication Host,这种host方式非常简单。在创建宿主程序时,需要为宿主指定宿主服务的类型,这里的类型要使用实现服务的类,最好不要使用接口类型。
创建宿主对象后,接下来为宿主添加了一个服务的终结点,终结点中第一个参数是指定了协议实现的类型,本例使用的是接口协议,所以要配置为相应的接口类型;第二个参数指定了绑定的类型;第三个参数则指定了终结点的URI地址,URI地址要配置服务具体实现的类URL地址。
接下来为宿主添加了一个行为(Behavior),并为行为公开了元数据,这种行为在创建时也可以不强加给服务,也就是说在添加宿主时,服务的行为定义是可选的,也可以不定义。

结语

本文主要针对WCF在客户端进行配置时所使用的基本的配置节做了详细的讨论,主要是Service、Binding和Behavior的应用,另外需要注意的是在客户端进行服务配置时不建议采用代码配置的方法,最好使用xml文件进行发布配置,这样能很好的修改。最后还有在添加WCF时一定要根据不同的类别添加需要的WCF,WCF中有类库和Application两种,它们所针对的Host是不同的,如果是类库的话往往用来配置Console Application作为Host,如果是Application类的往往用来配置网站服务,否则在使用时很容易出错。

来自 http://www.uml.org.cn/zjjs/201503125.asp
相关参考资料:
http://www.uml.org.cn/zjjs/201503125.asp
http://www.cnblogs.com/weichuo/archive/2008/07/09/1238979.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容