WCF 第一章 基礎 為一個ASMX服務實現一個WCF客戶端

weixin_34377065發表於2011-06-22

WCF客戶端可以呼叫任何基於標準的服務而不用考慮目標宿主環境。在.NET Framework 1.1 上建立的ASMX網路服務是完全相容的。由WS-I 1.1基本概況定義的標準確保它們可以被WCF呼叫。

支援工具

就像呼叫一個WCF服務,你可以使用新增服務引用(ASR)或者Svcutil.exe來建立代理類和配置檔案來呼叫ASMX服務操作。在這些被建立以後,客戶端通過例項化代理呼叫方法來與ASMX網路服務通訊。同樣的,你可以使用新增網路服務引用(AWR)或者wsdl.exe 來生成代理類和配置檔案。然後在例項被建立以後,客戶端在代理上呼叫方法來和服務通訊。

對於新生成的呼叫已存在的ASMX網路服務的客戶端應用,最好是使用ASR或者svcutil.exe.對於那些已經通過ASR/svcutil.exe產生代理類和配置檔案的已有應用,最好是繼續使用AWR/wsdl.exe.這種方式,客戶端不用使用兩種型別的代理類和配置檔案來和ASMX服務通訊。如果客戶端被修改去使用basicHttpBinding來呼叫新的WCF服務,你可以仍然使用AWR/wsdl.exe來為WCF服務產生新的代理。

0_1284980644f0D5.gif

不論你是否使用svcutil.exe或者wsdl.exe來生成代理類,客戶端使用這個代理來訪問遠端服務。額外的,為了支援代理類在客戶端應用程式的app.config中增加了入口。

生成客戶端代理類和配置檔案

如果你在修改一個已存在的已經有ASMX代理的客戶端,你應該使用新增服務引用(ASR).列表1.13顯示了使用通過新增服務引用生成的客戶端程式碼呼叫服務操作的過程。

列表1.13 使用新增服務引用新增生成的客戶端程式碼訪問一個ASMX服務

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ASMXReference.StockService proxy = 
                new ASMXReference.StockService();
            double p = proxy.GetPrice("msft");
            Console.WriteLine("Price:{0}", p);
            proxy.Close();
        }
    }
}

  列表1.14顯示了一個由Visual Studio通過新增服務引用生成的配置檔案。注意唯一的儲存在app.config中的屬性是服務的地址。 這將與列表1.16中的通過新增服務引用生成的app.config所描述的細節形成鮮明對比。通過新增服務引用新增的額外配置可以讓開發人員或者管理員改變引數,比如超時,而不用改任何程式碼。

列表1.14 通過為一個ASMX服務新增服務引用而生成的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings"
                  type="System.Configuration.ApplicationSettingsGroup,
                  System, Version=1.0.0.0, Culture=neutral,
                  PublicKeyToken=b77a5c561934e089">
      <section name="Clinet.Properties.Settings"
               type="System.Configuration.ClientSettingsSection,
               System, Version=1.0.0.0, Culture=neutral,
               PublicKeyToken=b77a5c561934e089
               requirePermission=false"/>
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <Client.Properties.Settings>
      <setting name="Client_ASMXReference_StockService"
               serializeAs="string">
        <value>http://localhost/asmx/service.asmx</value>
      </setting>
    </Client.Properties.Settings>
  </applicationSettings>
</configuration>
 

  如果你在建立一個沒有ASMX代理的客戶端,你應該使用新增服務引用以便於你使用新的代理來開始一個新的工程。列表1.15顯示了和一個ASMX服務一起使用的由新增服務引用生成代理的客戶端程式碼。注意終結點的名字,StockServiceSoap,必須在代理生成之前被建立。這是因為新增服務引用會新增兩個終結點到app.config檔案中:一個使用basicHttpBinding,另一個使用與SOAP 1.1適應的自定義繫結。

列表1.15 使用新增服務引用代理訪問ASMX的客戶端程式碼

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using(WCFReference.StockServiceSoapClient proxy = 
                new client.WCFReference.StockServiceSoapClient("StockServiceSoap"))
            {
                double p = proxy.GetPrice("msft");
                Console.WriteLine("Price:{0}", p);
            }
        }
    }
}

列表1.16顯示了由Visual Studio新增服務引用新增的為一個ASMX服務使用的配置檔案。注意繫結的全部細節和終結點資訊是從ASMX服務獲取的,它們儲存於app.config中。也要注意有兩個終結點被定義。第一個終結點,StockServiceSoap,使用basicHttpBinding,與WS-I基本架構1.1標準一起編譯。第二個終結點,StockServiceSoap12,使用自定義繫結和後來的SOAP協議通訊。因為ASMX是WS-I基本框架1.1標準相容的,所以1.1終結點也被使用。

列表1.16 由新增服務引用生成的為一個ASMX服務使用的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="StockServiceSoap" closeTimeout="00:01:00"
                 openTimeout="0:01:00" receiveTimeout="00:01:00"
                 sendTimeout="00:01:00" allowCookies="false"
                 bypassProxyOnLocal="false"
                 hostNameComparisonMode="StrongWildcard" 
                 maxBufferSize="65536" maxBufferPoolSize="524288" 
                 maxReceivedMessageSize="65536" 
                 messageEncoding="Text" textEncoding="utf-8" 
                 transferMode="Buffered" 
                 useDefaultWebProxy="true">
          <readerQuotas maxDepth="32"
                        maxStringContentLength="8192" maxArrayLength="16384" 
                        maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
      <customBinding>
        <binding name="StockService12">
          <textMessageEncoding maxReadPoolSize="64" 
                               maxWritePoolSize="16" 
                               messageVersion="Soap12" writeEncoding="utf-8">
            <readerQuotas maxDepth="32"
                          maxStringContentLength="8192"
                          maxArrayLength="16384"
                          maxBytesPerRead="4096" 
                          maxNameTableCharCount="16384"/>
          </textMessageEncoding>
          <httpTransport manualAddressing="false"
                         maxBufferPoolSize="524288"
                         maxReceivedMessageSize="65536"
                         allowCookies="false"
                         authenticationScheme="Anonymous"
                         bypassProxyOnLocal="false"
                         hostNameComparisonMode="StrongWildcard"
                         keepAliveEnabled="true"
                         maxBufferSize="65536"
                         proxyAuthenticationScheme="Anonymous"
                         realm="" transferMode="Buffered" 
                         unsafeConnectionNtlmAuthentication="false" 
                         useDefaultWebProxy="true"/>
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost/asmx/service.asmx" 
                binding="basicHttpBinding" 
                bindingConfiguration="StockServiceSoap" 
                contract="Client.WCFReference.StockServiceSoap"
                name="StockServiceSoap"/>
      <endpoint address="http://localhost/asmx/service.asmx"
                binding="customBinding"
                bindingConfiguration="StockServiceSoap12"
                contract="Client.WCFReference.StockServiceSoap" 
                name="StockServiceSoap12"/>
    </client>
  </system.serviceModel>
</configuration>

相關文章