none
通过更改在创建 XML 读取器时所使用的 XmlDictionaryReaderQuotas 对象的 MaxArrayLength 属性,可增加此配额 RRS feed

  • 问题

  • 通过WCF传输byte,当byte过大时提示“远程服务器返回了意外响应: (400) Bad Request”,数据减小后提示“远程服务器返回了意外响应: (400) Bad Request”,

    依据http://social.msdn.microsoft.com/forums/zh-CN/bfcc28ee-a99c-4d2f-9774-7f9c679b9443/winform-wcf

    http://social.msdn.microsoft.com/Forums/zh-CN/5f529d31-1389-4940-8d34-c3169982e628/wcf-maxarraylength-?forum=wcfzhchs

    做了相关设置,依然不行。

    Server端 Web.config

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

      <system.web>
        <trace enabled="true" />
        <compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      <system.serviceModel>
        <bindings>     
          <basicHttpBinding>
            <binding name="BasicHttpBinding_WCFCycPOS" maxReceivedMessageSize="2147483647" maxBufferPoolSize ="524288" maxBufferSize ="2147483647"
              messageEncoding="Text" transferMode="Streamed" sendTimeout="00:10:00" >
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                            maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
            </binding>
          </basicHttpBinding>     
        </bindings>   
        <services>
          <service  name="WCFSVData.WCFCycPOS"  >       
            <endpoint address="" binding="basicHttpBinding"   name="BasicHttpBinding_WCFCycPOS" bindingConfiguration="BasicHttpBinding_WCFCycPOS"  contract="WCFSVData.WCFCycPOS" />
          </service>
            <behaviors>
          <serviceBehaviors>
            <behavior  name="">
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
            <behavior  name="WCFSVData.Service1Behavior" >        
              <dataContractSerializer maxItemsInObjectGraph="2147483647" />
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
     
    </configuration>

    App.config

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

      <system.web>
        <trace enabled="true" />
        <compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      <system.serviceModel>
        <bindings>     
          <basicHttpBinding>
            <binding name="BasicHttpBinding_WCFCycPOS" maxReceivedMessageSize="2147483647" maxBufferPoolSize ="524288" maxBufferSize ="2147483647"
              messageEncoding="Text" transferMode="Streamed" sendTimeout="00:10:00" >
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                            maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
            </binding>
          </basicHttpBinding>     
        </bindings>   
        <services>
          <service  name="WCFSVData.WCFCycPOS"  >       
            <endpoint address="" binding="basicHttpBinding"  behaviorConfiguration="WCFSVData.Service1Behavior"  name="BasicHttpBinding_WCFCycPOS" bindingConfiguration="BasicHttpBinding_WCFCycPOS"  contract="WCFSVData.WCFCycPOS" />
          </service>
          <!--<service  name="WCFnData.WCFCycServiceApp" behaviorConfiguration="WCFnData.WCFCycServiceApp" >
            <endpoint  binding="basicHttpBinding" name="BasicHttpBinding_WCFCycServiceApp" bindingConfiguration="BasicHttpBinding_WCFCycServiceApp" contract="WCFnData.WCFCycServiceApp" />
          </service>
          <service  name="WCFnDataLocal.WCFCycService" behaviorConfiguration="WCFnDataLocal.WCFCycService">
            <endpoint  binding="basicHttpBinding" name="BasicHttpBinding_WCFCycService" contract="WCFnDataLocal.WCFCycService" />
          </service>-->
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior  name="">
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
            <behavior  name="WCFSVData.Service1Behavior" >        
              <dataContractSerializer maxItemsInObjectGraph="2147483647" />
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
     
    </configuration>

    2014年6月13日 6:24

答案

  • 谢谢您的回复,我的问题解决了

    解决办法并非网上所说的需要behaviorConfiguration name 要与binding name匹配之类的

    我是直接取消这两个Name后程式运行正常。

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

      <system.web>
        <trace enabled="true" />
        <compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding  maxReceivedMessageSize="2147483647"
                     maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
                     receiveTimeout="00:01:00" openTimeout="00:01:00"
                     closeTimeout="00:01:00" sendTimeout="00:01:00">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647"   maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            </binding>
          </basicHttpBinding>
        </bindings>
        <services>
          <service name="ServiceReference.IService">
            <endpoint binding="basicHttpBinding"                  
                      bindingNamespace="http://localhost/CycPos_WS10/Service.svc"
                      contract="Services.MyService.ServiceContracts.IMyService" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    </configuration>

    参考

    http://stackoverflow.com/questions/7470530/problem-with-large-requests-in-wcf

    Found the solution...But still very strange!

    If I remove the name attribute from my binding tag and the bindingConfiguration attribute from my endpoint tag it all works. This means that the basicHttpBinding configuration is the default configuration for all basicHttpBinding endpoints

    感谢 Fuxiang Zhang提供的思路,非常感谢!

    2014年6月18日 3:02

全部回复

  •  
        <bindings>     
          <basicHttpBinding>
            <binding name="BasicHttpBinding_WCFCycPOS" maxReceivedMessageSize="2147483647" maxBufferPoolSize ="524288" maxBufferSize ="2147483647"
              messageEncoding="Text" transferMode="Streamed" sendTimeout="00:10:00" >
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                            maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
            </binding>
          </basicHttpBinding>     
        </bindings>   

    你好,

    如果我们想要增加WCF message 的上限大小,一般需要如下设置。

    <bindings>
        <basicHttpBinding>
            <binding name="basicHttp" allowCookies="true"
                     maxReceivedMessageSize="20000000" 
                     maxBufferSize="20000000"
                     maxBufferPoolSize="20000000">
                <readerQuotas maxDepth="32" 
                     maxArrayLength="200000000"
                     maxStringContentLength="200000000"/>
            </binding>
        </basicHttpBinding>
    </bindings>

    而在你的配置文件中没有设置 maxBufferSize。要注意的是服务端和客户端要有同样的设置。

    谢谢!

    2014年6月16日 12:04
    版主
  • Fuxiang 

    非常感谢您的回复,这个问题依据困扰我2周了,快整崩溃了。

    我的配置中有设定maxBufferSize ="2147483647",麻烦再帮我分析下好吗?

    是否可以通过Skype Or QQ与您交流下呢,我的Skype:josenlee2008

    QQ:35321413.

    拜托了,绝望中.....

    Fuxiang Zhang - MSFT 的头像

    Fuxiang Zhang - MSFT

    pactera

    MSFT CSG

    2014年6月17日 3:39
  • 我对DataSet压缩后再传输,出现错误如下:

    格式化程序尝试对消息反序列化时引发异常: 对操作“InSpin”的请求消息正文进行反序列化时出现错误。读取 XML 数据时,超出最大数组长度配额(16384)。通过更改在创建 XML 读取器时所使用的 XmlDictionaryReaderQuotas 对象的 MaxArrayLength 属性,可增加此配额。 行 1,位置 64411。

    MaxArrayLength 在配置中已有设定。

    2014年6月17日 3:46
  • 我对DataSet压缩后再传输,出现错误如下:

    格式化程序尝试对消息反序列化时引发异常: 对操作“InSpin”的请求消息正文进行反序列化时出现错误。读取 XML 数据时,超出最大数组长度配额(16384)。通过更改在创建 XML 读取器时所使用的 XmlDictionaryReaderQuotas 对象的 MaxArrayLength 属性,可增加此配额。 行 1,位置 64411。

    MaxArrayLength 在配置中已有设定。

    你可以尝试使用custom binding 如下所示:

    <bindings>
            <customBinding>
                <binding name="MashCustomBinding"
                        closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
                    <textMessageEncoding messageVersion="Soap11" maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
                        <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
                    </textMessageEncoding>
                    <httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647"/>
                </binding>
            </customBinding>
        </bindings>
    

    另外, 我建议你从以下相似的帖子中找些信息。

    http://stackoverflow.com/questions/13937555/wcf-the-maximum-array-length-quota-16384-has-been-exceeded-while-reading-xml

    http://stackoverflow.com/questions/3068076/wcf-service-the-maximum-array-length-quota-16384-has-been-exceeded

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/26f6a581-fcca-4f3a-a151-bdc959385db9/cthe-maximum-array-length-quota-16384-has-been-exceeded-while-reading-xml-data-this-quota-may?forum=wcf

    希望有些帮助,谢谢

    2014年6月17日 5:35
    版主
  • 感谢您的回复!

    按照您推荐的方式:

    提示如下错误:

    服务 http://pc0937/CycPos_WS10/Service.svc 不支持内容类型 application/soap+msbin1。客户端和服务绑定可能不匹配。

    Web.config

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

      <system.web>
        <trace enabled="true" />
        <compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      <system.serviceModel>
        <bindings>    
          <customBinding>
            <binding name="MashCustomBinding"
                    closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
              <textMessageEncoding messageVersion="Soap11" maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
                <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
              </textMessageEncoding>
              <httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647"/>
            </binding>
          </customBinding>
        </bindings>
        <!--name 必须与代码中的host实例初始化的服务一样 behaviorConfiguration 行为配置 -->
        <services>
        <service name="DRP.myServer" behaviorConfiguration="DRP.myServerDataBehavior">
          <host>
            <!--添加调用服务地址-->
            <baseAddresses>
              <add baseAddress="http://PC0937/CycPos_WS10/Service.svc"/>
            </baseAddresses>
          </host>
          <!--添加契约接口   contract="WcfDemo.IService1" WcfDemo.IService1为契约接口   binding="wsHttpBinding" wsHttpBinding为通过Http调用-->
          <endpoint binding="customBinding" behaviorConfiguration="myEndpointBehavior" contract="DRP_BaseData.IServiceMyServer" bindingConfiguration="MashCustomBinding">
          </endpoint>
        </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="myEndpointBehavior">
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </endpointBehaviors>
          <!--下面的serviceBehaviors不设置也可以通过-->
          <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="DRP.myServerDataBehavior">
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点-->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <!--serviceThrottling maxConcurrentCalls="3000" maxConcurrentInstances="3000" maxConcurrentSessions="30000"/-->
              <dataContractSerializer maxItemsInObjectGraph="65536000"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="false"
          multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>  
    </configuration>

    APP.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
      </configSections>
      <system.serviceModel>
        <behaviors>
          <endpointBehaviors>
            <behavior name="myEndpointBehavior">
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding_WCFCycPOS" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
              maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
              messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
              <security mode="None">
                <transport clientCredentialType="None" proxyCredentialType="None"
                  realm="" />
                <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
            </binding>
            <binding name="BasicHttpBinding_WCFCycService" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
              maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
              messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="None">
                <transport clientCredentialType="None" proxyCredentialType="None"
                  realm="" />
                <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
            </binding>
            <binding name="BasicHttpBinding_WCFCycServiceApp" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
              maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
              messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="None">
                <transport clientCredentialType="None" proxyCredentialType="None"
                  realm="" />
                <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
            </binding>
          </basicHttpBinding>
          <customBinding>
            <binding name="customBinding">
              <binaryMessageEncoding>
                <readerQuotas maxDepth="64" maxStringContentLength="2147483647"
                  maxArrayLength="2147483647" />
              </binaryMessageEncoding>
              <httpTransport maxReceivedMessageSize="2147483647" />
            </binding>
          </customBinding>
        </bindings>
        <client>
          <endpoint address="http://PC0937/CycPos_WS10/WCFCycPOS.svc" behaviorConfiguration="myEndpointBehavior"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WCFCycPOS"
            contract="WCFSVData.WCFCycPOS" name="BasicHttpBinding_WCFCycPOS" />
          <endpoint address="http://PC0937/CycPos_WS10/WCFCycService.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WCFCycService"
            contract="WCFnDataLocal.WCFCycService" name="BasicHttpBinding_WCFCycService" />
          <endpoint address="http://PC0937/CycPos_WS10/WCFCycServiceApp.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WCFCycServiceApp"
            contract="WCFnData.WCFCycServiceApp" name="BasicHttpBinding_WCFCycServiceApp" />
          <endpoint address="http://PC0937/CycPos_WS10/Service.svc" behaviorConfiguration="myEndpointBehavior"
            binding="customBinding" bindingConfiguration="customBinding"
            contract="ServiceReference.IService" name="BasicHttpBinding_IService" />
        </client>
      </system.serviceModel>
    </configuration>

    程式中调用:

    ConnData.ServiceReference.ServiceClient s1 = new ServiceReference.ServiceClient("BasicHttpBinding_IService");

      string str = s1.InSpin(CYCNO, yymm, dt, partkind);

    其中dt是二进制数据,如果很小则可以上传,稍大就出现超过16384的提示。

    PS:我目前测试就是从服务器中抓取一个表至客户端(下载正常),不做任何修改再上传至服务端(上传报错)。

    烦请再协助分析下原因,非常感谢!


    2014年6月17日 6:19
  • 欢迎回来,

    在你服务端的配置中CustomBinding用的是 textMessageEncoding

     <customBinding>
             <binding name="MashCustomBinding"
                     closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
               <textMessageEncoding messageVersion="Soap11" maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
                 <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
               </textMessageEncoding>

    而你的客户端的CustomBinding用的是binaryMessageEncoding.

    <customBinding>
             <binding name="customBinding">
               <binaryMessageEncoding>
                 <readerQuotas maxDepth="64" maxStringContentLength="2147483647"
                   maxArrayLength="2147483647" />
               </binaryMessageEncoding

    请保证客户端和服务端使用相同的Endpoint(ABC)

    谢谢!

    2014年6月17日 8:37
    版主
  • 谢谢您的回复,我的问题解决了

    解决办法并非网上所说的需要behaviorConfiguration name 要与binding name匹配之类的

    我是直接取消这两个Name后程式运行正常。

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

      <system.web>
        <trace enabled="true" />
        <compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2147483647" />
      </system.web>
      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding  maxReceivedMessageSize="2147483647"
                     maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
                     receiveTimeout="00:01:00" openTimeout="00:01:00"
                     closeTimeout="00:01:00" sendTimeout="00:01:00">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647"   maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            </binding>
          </basicHttpBinding>
        </bindings>
        <services>
          <service name="ServiceReference.IService">
            <endpoint binding="basicHttpBinding"                  
                      bindingNamespace="http://localhost/CycPos_WS10/Service.svc"
                      contract="Services.MyService.ServiceContracts.IMyService" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    </configuration>

    参考

    http://stackoverflow.com/questions/7470530/problem-with-large-requests-in-wcf

    Found the solution...But still very strange!

    If I remove the name attribute from my binding tag and the bindingConfiguration attribute from my endpoint tag it all works. This means that the basicHttpBinding configuration is the default configuration for all basicHttpBinding endpoints

    感谢 Fuxiang Zhang提供的思路,非常感谢!

    2014年6月18日 3:02