【问题标题】:HttpClient posting byte[] to WCF service produces error: The maximum array length quota (16384) or the maximum itemsHttpClient 将 byte[] 发布到 WCF 服务产生错误:最大数组长度配额 (16384) 或最大项
【发布时间】:2012-06-19 13:43:59
【问题描述】:

我有一个可以接受byte[] 的 WCF 服务。我正在使用HttpClient 创建一个客户端并收到以下错误。我在网上看到您必须在服务器和客户端上设置readerQuotas,但是如何在HttpClient上设置这些设置?

错误:

反序列化 RTM.API.Resources.UGCRequest 类型的对象时出错。读取 XML 数据时,已超出最大数组长度配额 (16384) 或对象图中的最大项目配额。可以通过更改 XmlDictionaryReaderQuotas 上的 MaxArrayLength 属性或 MaxItemsInObjectGraph 设置来增加这些配额。

服务器配置:

    <standardEndpoints>
        <webHttpEndpoint>
            <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"/>
            <standardEndpoint name="DirectoryEndpoint"/>
        </webHttpEndpoint>
    </standardEndpoints>
    <services>
        <service name="API.Service.UGCService" behaviorConfiguration="DataServiceBehavior">
            <endpoint contract="API.Service.UGCService" kind="webHttpEndpoint" endpointConfiguration="" binding="webHttpBinding" bindingConfiguration="BigHttpBinding"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="DataServiceBehavior">
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <dataContractSerializer maxItemsInObjectGraph="2147483644"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <webHttpBinding>
            <binding name="BigHttpBinding" transferMode="Buffered" maxReceivedMessageSize="2147483647" >
                <readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            </binding>
        </webHttpBinding>
    </bindings>

客户端代码:

using (HttpClient client = new HttpClient(apiPath))
            {
                using (HttpRequestMessage request = new HttpRequestMessage(method, finalUrl))
                {
                    request.Headers.Accept.AddString("application/json");
                    request.Headers.Add("Authorization", sb.ToString());

                    if (method == "POST" || method == "PUT")
                    {
                        if (requestBody.Count() == 0)
                            request.Headers.ContentLength = 0;
                        else
                        {
                            request.Content = HttpContent.Create(APM6.Utils.Serialize(requestBody), "application/json");
                        }
                    }

                    using (HttpResponseMessage response = client.Send(request))
                    {
                        return response.Content.ReadAsString();
                    }
                }
            }

【问题讨论】:

  • 作为一个题外话,我已经在 WCF 上苦苦挣扎 6 个月了,我建议使用它来公开 JSON 接口(它有很多错综复杂不付出努力)。如果您想坚持使用 Microsoft 技术并可以评估替代方案,请查看 WebAPI。

标签: wcf wcf-client


【解决方案1】:

readerQuotas 是一组额外的约束,WCF 实施这些约束以防止拒绝服务 (DOS) 攻击。

HttpClient 没有实现该保护,因此您无需担心额外的客户端配置。

您看到该错误是因为 &lt;readerQuotas maxArrayLength="2147483647" /&gt; 由于某种原因未应用于您的服务器端点。您可以使用svcutil.exewcftestclient.exe 来证明这一点。

尝试使用这些工具生成配置文件,您可能会在该配置文件中看到&lt;readerQuotas maxArrayLength="16384" /&gt;。这意味着服务器部分没有将扩展值应用于maxArrayLength

如果是这样,请使用服务器端配置或代码以确保应用该配置。

【讨论】:

    【解决方案2】:

    试试这个:

      <endpointBehaviors>
        <behavior name ="namespace1.namespace1Behavior">
          <dataContractSerializer maxItemsInObjectGraph ="2147483647"/>
        </behavior>
        <behavior name="mybehavior">
          <transactedBatching maxBatchSize="2147483647"/>
        </behavior>
      </endpointBehaviors>
    
      <serviceBehaviors>
        <behavior name="namespace1.namespace1Behavior">
          <dataContractSerializer maxItemsInObjectGraph ="2147483647"/>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    

    【讨论】:

      【解决方案3】:

      在这种情况下,您需要在客户端上的唯一设置是 MaxResponseContentBufferSize

      但是,您的问题是在服务器上的反序列化过程中出现的。您可能需要添加maxBufferPoolSize="2147483647" maxBufferSize="2147483647" 作为绑定参数

      这似乎仍然与错误消息不完全对应。确保服务行为与问题中显示的配置文件相对应,而不是与某些不同的副本相对应。

      【讨论】:

      • 我将 maxBufferPoolSize="2147483647" maxBufferSize="2147483647" 添加到绑定中,但仍然出现错误。错误肯定发生在服务器上吗?还有其他想法吗?
      • @TroyBarlow - 是的,请求反序列化正在服务器上进行。我认为您正在以编程方式隐藏一些已发布的服务器配置或在服务器端代码中使用ServiceBehaviorAttribute(获取默认的MaxItemsInObjectGraph 65536)。请注意,在序列化或反序列化数组时,每个数组条目都算作一个单独的对象。如果是这种情况,请在属性中也设置MaxItemsInObjectGraph
      猜你喜欢
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 2013-09-15
      • 2015-04-02
      • 1970-01-01
      相关资源
      最近更新 更多