• WCF配置文件详解


    上篇文章主要讨论了WCF的基本内容,其中包括WCF的术语、创建方法及WCF在开发过程中使用的意义,它不仅能够提供程序之间的通信,而且还能提供程序和数据间的通信,WCF提供了多样化的程序之间的通信,不仅支持App的通信而且还支持web与应用程序之间的通信,可谓是功能强大。虽然上文讨论了WCF的基本使用方法,并做了很多Demo,但是都只是关于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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    上例将配置信息写入到了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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在上面的代码中添加了一个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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    三、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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    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();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

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

    结语

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

    xml配置详解

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.ServiceModel>
        <!-- services元素包含应用中驻留的所有service的配置要求-->
        <services>
          <!-- 每个服务的配置
                属性说明:
                name -指定这个service配置是针对的那个服务,为一个实现了某些Contract的服务类的完全限定名
                      (名称空间.类型名),ServiceHost载入一个服务后,会到配置文件中的<services>下找有没有
                      name属性跟服务匹配的<service>的配置 
                behaviorConfiguration -指定在<serviceBehaviors>下的一个<behavior>的name,这个特定<behavior>给这个service制定了一些行为,比如服务是否允许身份模拟-->
          <service name="名称空间.类型名" behaviorConfiguration="behavior名">
            <host>
              <baseAddresses>
                <!-- 在此可以定义每种传输协议的baseAddress,用于跟使用同样传输协议Endpoint定义的相对地址组成完整的地址,但是每种传输协议只能定义一个baseAddress。HTTP的baseAddress同时是service 对外发布服务说明页面的URL-->
                <add baseAddress="http://address" />
              </baseAddresses>
              <timeouts></timeouts>
            </host>
            <!-- 每个服务可以有多个Endpoint,下面<endpoint>元素对每个Endpoint分别进行配置
                    属性说明:
                    address -指定这个Endpoint对外的URI,这个URI可以是个绝对地址,也可以是个相对于baseAddress的
                              相对地址。如果此属性为空,则这个Endpoint的地址就是baseAddress
                    binding -指定这个Endpoint使用的binding,这个banding可以是系统预定义的9个binding之一,
                              比如是basicHttpBinding,也可以是自定义的customBinding。binding决定了通讯的类型、
                             安全、如何编码、是否基于session、是否基于事务等等
                    contract -指定这个Endpoint对应的Contract的全限定名(名称空间.类型名),这个Contract应该被
                               service元素的name指定的那个service实现 
                    bindingConfiguration -指定一个binding的配置名称,跟<bindings>下面同类<binding>的name匹配
                       behaviorConfiguration -指定这个endpoint的behavior,指向<behaviors>下的同样配置名称的<endpointBehaviors>
                    name - Endpoint的名称,可选属性,每个Contract都可以有多个Endpoint,但是每个Contract对应的
                           多个Endpoint名必须是唯一的-->
            <endpoint address="URI" binding="basicHttpBinding" contract="Contract全限定名" bindingConfiguration="binding名" behaviorConfiguration="String" name="">
              <!-- 用户定义的xml元素集合,一般用作SOAP的header内容-->
              <headers>
                <!-- 任何xml内容-->
              </headers>
            </endpoint>
          </service>
        </services>
    
        <bindings>
          <!-- 指定一个或多个系统预定义的binding,比如<basicHttpBinding>,当然也可以指定自定义的customBinding,
                然后在某个指定的binding下建立一个或多个配置,以便被Endpoint来使用这些配置-->
          <basicHttpBinding>
            <!-- 某一类的binding的下面可能有多个配置,binding元素的name属性标识某个binding-->
            <binding name="binding名">
            </binding>
          </basicHttpBinding>
        </bindings>
        <!-- 定义service和Endpiont行为-->
        <behaviors>
          <!-- 定义service的行为-->
          <serviceBehaviors>
            <!-- 一个或多个系统提供的或定制的behavior元素
                    属性说明:
                    name -一个behavior唯一标识,<service>元素下<endpoint>的behaviorConfiguration属性指向这个name-->
            <behavior name="此Behavior名称">
              <!-- 指定service元数据发布和相关信息
                        属性说明:
                        httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据
                        httpGetUrl -如果httpGetEnabled为true,这个属性指示使用哪个URL地址发布服务的WSDL,
                                     如果这个属性没有设置,则使用服务的HTTP类型的baseAddress后面加上?WSDL-->
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://URI:port/address" />
              <!--指定验证服务端的凭据-->
              <serviceCredentials>
                <!--指定服务端的证书
                            属性说明:
                            storeName -证书的存储区,可能值为:AddressBook,AuthRoot,CertificateAuthority
                                        Disallowed,My,Root,TrustedPeople,TrustedPublisher
                            storeLocation -证书存储位置,可能值为:CurrentUser,LocalMachine
                                x509FindType -查找证书的方式,可能的值:FindBySubjectName,FindByThumbPrint,FindByIssuerName......
                                findValue -对应查找方式的要查找证书的值                -->
                <serviceCertificate storeName="存储区" storeLocation="存储位置" x509FindType="FindBySubjectName" findValue="server1" />
              </serviceCredentials>
    
            </behavior>
          </serviceBehaviors>
          <!-- 定义Endpiont的行为-->
          <endpointBehaviors>
            <!-- 一个或多个系统提供的或定制的behavior元素
                   属性说明:
                    name -一个behavior唯一标识,<client>元素下<endpoint>的behaviorConfiguration属性指向这个name-->
            <behavior name="此Behavior名称">
              <!--指定客户端的凭据-->
              <clientCredentials>
                <!--指定客户端的证书
                            属性说明:
                            storeName -证书的存储区,可能值为:AddressBook,AuthRoot,CertificateAuthority
                                        Disallowed,My,Root,TrustedPeople,TrustedPublisher
                            storeLocation -证书存储位置,可能值为:CurrentUser,LocalMachine
                                x509FindType -查找证书的方式,可能的值:FindBySubjectName,FindByThumbPrint,FindByIssuerName......
                                findValue -对应查找方式的要查找证书的值                -->
                <clientCertificate storeName="存储区" storeLocation="存储位置" x509FindType="FindBySubjectName" findValue="Client1" />
                <serviceCertificate>
                  <authentication certificateValidationMode="None" />
                </serviceCertificate>
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <!-- 包含客户端跟服务端连接使用到的Endpoint的配置-->
        
        
        <client>
          <!-- 每个客户端Endpoint设置
                属性说明:
                address -对应到服务端这个Endpoint的address
                binding -指定这个Endpoint使用的binding,这个banding可以是系统预定义的9个binding之一,
                          比如是basicHttpBinding
                contract -指定这个Endpoint对应的Contract的全限定名(名称空间.类型名)
                name - Endpoint的配置名,客户端代理类的构造方法中的endpointConfigurationName对应到这个name
                bindingConfiguration -指定客户端binding的具体设置,指向<bindings>元素下同类型binding的name
                  behaviorConfiguration -指定这个endpoint的behavior,指向<behaviors>下的同样配置名称的<endpointBehaviors>-->
          <endpoint address="URI" binding="basicHttpBinding" bindingConfiguration="binding名" behaviorConfiguration="String" contract="Contract全限定名" name="endpoint配置名" >
            <!-- 用于客户端验证服务端身份,可选以下一种方式验证服务端-->
            <identity>
              <userPrincipalName></userPrincipalName>
              <servicePrincipalName></servicePrincipalName>
              <!--如果客户端验证是windows,这里指定DNS名;如果是Certificate,这里指定证书subject name-->
              <dns></dns>
              <rsa></rsa>
              <!--指定服务端证书的公钥
                              属性说明:
                               encodedValue -服务端证书的公钥的base64编码,用于加密用户名和密码-->
              <certificate encodedValue=""></certificate>
              <!-- 用户指定在客户端证书存储区内的服务端证书
                            属性说明:
                            storeName -证书的存储区,可能值为:AddressBook,AuthRoot,CertificateAuthority
                                        Disallowed,My,Root,TrustedPeople,TrustedPublisher
                            storeLocation -证书存储位置,可能值为:CurrentUser,LocalMachine
                                x509FindType -查找证书的方式,可能的值:FindBySubjectName,FindByThumbPrint,FindByIssuerName......
                                findValue -对应查找方式的要查找证书的值                -->
              <certificateReference storeName="存储区" storeLocation="存储位置" x509FindType="FindBySubjectName" findValue="Client1" />
            </identity>
          </endpoint>
        </client>
      </system.ServiceModel>
    </configuration>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141

    原文链接:https://blog.csdn.net/zhang_xinxiu/article/details/41440551

  • 相关阅读:
    搭建Docker私有镜像仓库
    生产管理系统--制造订单
    Qt SQL:QSqlQueryModel、QSqlTableModel
    unity资源管理之Addressable
    设计模式之单例模式
    【gazebo要素10】制作移动的机器人
    【2023】Git版本控制-本地仓库详解
    MYSQL数据库的概念和sql语句
    STL中 Map 的基本用法
    力扣(141.21)补9.1
  • 原文地址:https://blog.csdn.net/spw55381155/article/details/125553794