2012年7月19日 星期四

[WCF] 如何產生大量services的Proxy

利用Visual studio自動建立Proxy時,


出現以下錯誤訊息.


下載 http://localhost:7100/MyService/mex 時發生錯誤。
要求失敗,HTTP 狀態 400 : Bad Request
中繼資料包含無法解析的參照: 'http://localhost:7100/MyService/mex'
XML 文件 (1, 63595) 中有錯誤。
XML 文件 (1, 63595) 中有錯誤。
讀取 XML 資料時已經超過最大名稱表格字元計數配額 (16384)。名稱表格是一種資料結構,用來儲存在 XML 處理過程中所遇到的字串 - 具有不重複的項目名稱、屬性名稱及屬性值的冗長 XML 文件可能會觸發此配額限制。在建立 XML 讀取器時變更 XmlDictionaryReaderQuotas 物件上使用的 MaxNameTableCharCount 屬性,便可以增加此配額。 1,位置 63595
If the service is defined in the current solution, try building the solution and adding the service reference again.


檢查的結果是因為Services太多了(將Services少量的加入, 當達到某數量時, 錯誤訊息便出現了).
一開始以為增加Server設定內的maxNameTableCharCount就可以了, 結果失敗.
將Server設定內所有的訊息限制都調到最大(Int32.MaxValue), 結果失敗.
最後發現Client端的訊息限制也要跟著調大.

這邊的Client指的是devenv.exe(Visual Studio IDE),
Visual Stuido 2008開發環境下, 位置在 C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE
相對應的設定檔是 devenv.exe.config,
以下是各設定檔的內容:

@Server.config
<system.serviceModel>     
    <bindings>
        <customBinding >
          <!-- NOTE: Binding的類型及名稱, Client需與Server的一致 -->
            <binding name="largeServiceBinding" >
                <textMessageEncoding>
                  <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                                maxArrayLength="2147483647" maxBytesPerRead="2147483647"
                                maxNameTableCharCount="2147483647" />
                  </textMessageEncoding>

                <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647"
                               maxBufferSize="2147483647"/>
            </binding>
        </customBinding>
    </bindings>

    <services>
              <endpoint address="mex"
                        binding="customBinding" bindingConfiguration="largeServiceBinding"
                        contract="IMetadataExchange" />
              <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:7100/MyService"/>              
                </baseAddresses>
              </host>
    </service>
</system.serviceModel>

@devenv.exe.config
<system.serviceModel>
    <client>
        <!-- NOTE: Endpoint的name需設定為"http" -->
        <endpoint name="http" binding="customBinding" bindingConfiguration="largeServiceBinding"
                  contract="IMetadataExchange" />
    </client>

    <bindings>
        <customBinding>
            <!-- NOTE: Binding的類型及名稱, Client需與Server的一致 -->
            <binding name="largeServiceBinding" >
                <textMessageEncoding>
                    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                                  maxArrayLength="2147483647" maxBytesPerRead="2147483647"
                                  maxNameTableCharCount="2147483647" />
                </textMessageEncoding>

                <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647"
                               maxBufferSize="2147483647"/>
            </binding>
        </customBinding>
    </bindings>
   
</system.serviceModel>


在devenv.exe.config的設定內, Endpoint的name需設定為"http",
而Server端的name可任意指派,
這一點還不太明白, 還請各位先進不吝指教


Reference:
http://stackoverflow.com/questions/2765598/wcf-the-maximum-nametable-character-count-quota-16384-has-been-exceeded-whil