2009-12-03 52 views
6

如何確保WCF的ChannelFactory在XML配置使用綁定設置(的MaxArrayLength被忽略)如何確保WCF的ChannelFactory在XML配置使用綁定設置(的MaxArrayLength被忽略)

您好,我是新來的WCF並編寫我的第一個Wcf服務和客戶端。我更喜歡不使用 工具來生成配置;我寧願自己寫配置。我試圖用 解決的問題是客戶端通過netTcp與服務進行通信。服務 可能會返回非常大的有效負載(超過默認的 readerQuotas.maxArrayLength)。當字節流有效載荷相對較低(即低於它認爲約爲16K的默認值)時,我最初開發的組件工作正常。 我可以通過創建綁定並將MaxArrayLength 設置爲一個足夠大的值來編程解決此問題。但是,我需要能夠在 xml配置中執行相同的操作。

我的app.config(客戶端)是:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 

     <client> 
      <endpoint address="net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/" 
       binding="netTcpBinding" bindingConfiguration="unsecureNetTcpBinding" 
       contract="WcfDataServiceLib.IRemoteDataRequester" 
       name="DataRequesterEndpoint" /> 
     </client> 

     <bindings> 
      <netTcpBinding> 
       <binding name="unsecureNetTcpBinding" maxReceivedMessageSize="2147483647"> 
        <readerQuotas maxArrayLength="1000000" /> 
        <security mode="None" /> 
       </binding> 
      </netTcpBinding> 
     </bindings> 

    </system.serviceModel> 
</configuration> 

代碼來創建客戶端代理如下:

private void Init() 
{ 
    var address = new EndpointAddress(@"net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/"); 
    const string endpointName = "DataRequesterEndpoint"; 

    ChannelFactory<IRemoteDataRequester> factory = new ChannelFactory<IRemoteDataRequester>(
     endpointName); 

    IRemoteDataRequester proxy = factory.CreateChannel(address); 

    // call business methods on proxy ... 
} 

注意,代碼是由可變連接到配置'endpointName'。

服務端配置(我不認爲這是相關的,但爲了保持完整性):

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <services> 
      <service name="WcfDataServiceLib.RemoteDataRequesterService" behaviorConfiguration="WcfDataServiceLib.RemoteDataRequesterServiceBehavior"> 
       <host> 
        <baseAddresses> 
         <add baseAddress = "net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService" /> 
         <add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfDataService/RemoteDataRequesterService/"/> 
        </baseAddresses> 
       </host> 
       <endpoint address ="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig" contract="WcfDataServiceLib.IRemoteDataRequester"> 
        <identity> 
         <dns value="localhost"/> 
        </identity> 
       </endpoint> 
       <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 

      </service> 
     </services> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="WcfDataServiceLib.RemoteDataRequesterServiceBehavior"> 
        <serviceMetadata httpGetEnabled="False"/> 
        <serviceDebug includeExceptionDetailInFaults="True" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 

     <bindings> 
      <netTcpBinding> 
       <binding name="netTcpBindingConfig" receiveTimeout="00:00:30"> 
        <readerQuotas maxArrayLength="1000000"/> 
       </binding> 
       <binding name="netTcpReliableSession" receiveTimeout="00:00:30" > 
        <reliableSession enabled="true"/> 
       </binding> 
      </netTcpBinding> 
     </bindings> 

    </system.serviceModel> 
</configuration> 

當我運行方案中的客戶端,其中一個大的字節流服務返回, 拋出異常並且異常內的消息是:

發生通信錯誤:套接字連接被中止。這可能是由於處理您的消息時發生錯誤或由於遠程主機 或底層網絡資源問題超出接收超時而導致 。本地套接字超時是'00:00:59.9687494'

(如立即發生錯誤這不是超時。)

如前所述,我可以以編程方式解決這個問題如下:

var binding = new NetTcpBinding 
{ 
    ReaderQuotas = { MaxArrayLength = 10000000 } 
}; 

return new ChannelFactory<IRemoteDataRequester>(binding); 

這工作正常,但我需要通過配置爲測試目的。

我也曾嘗試以下操作:

var binding = new NetTcpBinding("unsecureNetTcpBinding"); 
return new ChannelFactory<IRemoteDataRequester>(binding); 

但是,這沒有什麼區別。

所以我的問題是,爲什麼,當我從端點配置創建通道,其中包括一個綁定的MaxArrayLength設置爲合適的值,這個值是否被忽略?

很多問候。

好的,我找到了解決方案。配置一直在工作。然而,我提供的配置(「不安全的NetTcpBinding」),我從代碼示例說明http服務(不是我所設計的網絡tcp服務)的代碼示例中找到的。流氓一塊配置是 '安全模式=「無」' 當我拿出這個,它的工作。如果我更改readerQuotas maxArrayLength,則按我的要求應用。我的代碼工作原因是因爲我沒有將安全模式設置爲none。感謝您的意見和協助。

回答

1

我認爲問題可能是在配置你的號碼只有6個零,而在代碼中你有7個零。也許?

0

也許MaxArrayLength不是要設置的正確屬性。

嘗試「MAXBUFFERSIZE」和「MaxBufferPoolSize」:

<bindings> 
     <netTcpBinding> 
      <binding name="unsecureNetTcpBinding" 
        maxBufferSize="2147483647" 
        maxBufferPoolSize="2147483647" 
        maxReceivedMessageSize="2147483647"> 
       <readerQuotas maxArrayLength="1000000" /> 
       <security mode="None" /> 
      </binding> 
     </netTcpBinding> 
    </bindings> 

但真正的問題是:如果你有大量的數據,你爲什麼不利用的WCF streaming?這正是它的目的。

http://www.haveyougotwoods.com/archive/2008/04/14/wcf-message-streaming.aspx

的MAXBUFFERSIZE等大小設置爲故意一個相當小的值 - 以避免拒絕服務攻擊。只需將這些啓動到MaxInt級別,就會使服務器容易受到這些DOS攻擊。

UPDATE:
試着這樣做: - 創建一個新的控制檯應用程序 - 添加引用System.Runtime.SerializationSystem.ServiceModel - 添加包含正是您的客戶端配置包含 一個app.config - 把這些線在您的控制檯應用程序代碼:

class Program 
    { 
     static void Main(string[] args) 
     { 
      NetTcpBinding binding = new NetTcpBinding("unsecureNetTcpBinding"); 
      int maxArrayLength = binding.ReaderQuotas.MaxArrayLength; 
      long maxReceivedMessageSize = binding.MaxReceivedMessageSize; 
     } 
    } 
  • 運行和調試 - 你得到了什麼價值觀我得到了你輸入的內容:binding.ReaderQuotas.MaxArrayLength爲「1000000」,binding.MaxReceivedMessageSize爲「2147483647」。

WCF確認並使用config中的這些設置 - 保證有120%。在你的應用程序中一定有其他的東西可腥味。

+0

我試着設置maxBufferSize,maxBufferPoolSize和maxReceivedMessageSize,但是這些都不能通過配置工作。只是爲了重申,我可以通過代碼與maxArrayLength解決這個問題,但我想知道如何通過配置做到這一點,歡呼 – Zephilim 2009-12-03 17:25:06

+0

我在配置中設置maxBufferSize和MaxArrayLength - 沒有問題。你的情況一定有其他事情發生...... – 2009-12-03 17:40:03