WCF 413 请求实体太大 - 自托管 WebHttpBinding

Posted

技术标签:

【中文标题】WCF 413 请求实体太大 - 自托管 WebHttpBinding【英文标题】:WCF 413 Request Entity Too Large - Self Hosted WebHttpBinding 【发布时间】:2014-04-07 15:29:26 【问题描述】:

关于这个问题有很多讨论,但是我现在已经尝试了所有可能的解决方案,我们仍然从服务器收到 413 Request Entity Too Large 错误。

我们的 WCF 服务通过 Azure Worker 角色自托管,不使用 IIS。我们所有的配置都在代码中指定:

var host = new ServiceHost(searchEngine);

// Create binding
var binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxBufferPoolSize = 2147483647;

var readerQuotas = new XmlDictionaryReaderQuotas

    MaxStringContentLength = 2147483647,
    MaxArrayLength = 2147483647,
    MaxBytesPerRead = 2147483647,
    MaxDepth = 2147483647,
    MaxNameTableCharCount = 2147483647
;

// Setting quotas on a BindingElement after the binding is created has no effect on that binding.
// See: https://***.com/questions/969479/modify-endpoint-readerquotas-programatically
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, readerQuotas, null);

binding.ReceiveTimeout = new TimeSpan(1, 0, 0);
binding.SendTimeout = new TimeSpan(1, 0, 0);

// Add the service endpoint
var ep = host.AddServiceEndpoint(
    typeof(ISearchEngine),
    binding,
    string.Format("https://0/SearchEngine", externalEndpoint));

ep.Behaviors.Add(new WebHttpBehavior());

// Increase the MaxItemsInObjectGraph quota for all operations in this service
foreach (var operation in ep.Contract.Operations)

    operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 10000000;


return host;

这是我们的客户端配置 - 也在代码中指定:

var binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxBufferPoolSize = 2147483647;

var readerQuotas = new XmlDictionaryReaderQuotas

    MaxStringContentLength = 2147483647,
    MaxArrayLength = 2147483647,
    MaxBytesPerRead = 2147483647,
    MaxDepth = 2147483647,
    MaxNameTableCharCount = 2147483647
;

// Setting quotas on a BindingElement after the binding is created has no effect on that binding.
// See: https://***.com/questions/969479/modify-endpoint-readerquotas-programatically
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, readerQuotas, null);

binding.ReceiveTimeout = new TimeSpan(1, 0, 0);
binding.SendTimeout = new TimeSpan(1, 0, 0);

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

var channelFactory = new ChannelFactory<ISearchEngine>(binding, endpointAddress);

channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());


// Increase the MaxItemsInObjectGraph quota for all operations in this service
foreach (var operation in channelFactory.Endpoint.Contract.Operations)

    operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 10000000;


return channelFactory.CreateChannel();

我唯一的预感可能是 SSL 连接有问题?有一些文章提到了特定于 IIS 的问题,但我不确定这是否与自托管服务有关。

非常感谢任何建议。

更新:

为了确认 SSL 是问题的预感,我暂时禁用了 SSL,然后发现问题消失了。

所以现在我需要弄清楚为什么 SSL 会导致问题。有很多关于类似问题的文档,但它仅与 IIS 托管服务有关(我们的服务是从 Windows 服务自托管的):

IIS7 - (413) Request Entity Too Large | uploadReadAheadSize

是否有人知道仅适用于自托管 WCF 服务的等效设置?

【问题讨论】:

【参考方案1】:

我发现了这个问题,感谢这篇看似无关的帖子:

http://forums.newatlanta.com/messages.cfm?threadid=554611A2-E03F-43DB-92F996F4B6222BC0&#top

这绝对是一个 SSL 问题,它与将 SSL 证书绑定到您托管的端口有关。您必须使用 netsh 绑定证书并将 clientcertnegotiation=enable 添加到绑定中。

在我们的例子中,我们已经在使用 netsh,因为我们使用的是不同的端口,所以我们的绑定现在看起来像这样:

netsh http add sslcert ipport=0.0.0.0:10100 certhash=000000089A6679262D845B650FDDE5390F0D86AB appid=000007b4-2d4b-4587-ae99-7a6627476f76 clientcertnegotiation=enable

对于那些通过 IIS 托管并更改 UploadReadAheadSize 的值的人,上面的论坛帖子指出这可能会导致 CPU 过高,而这个解决方案可能会更好。

【讨论】:

【参考方案2】:

如果你需要传输大数据,你应该使用 transferMode = "Streaming"。

看看这篇来自 MS 的论文:

http://msdn.microsoft.com/en-us/library/ms733742(v=vs.110).aspx

【讨论】:

谢谢。我也试过这个,但后来发现流模式不适用于我们正在使用的基本身份验证。也就是说,我们的数据很小:100kb - 200kb,所以我认为问题不在于缺少 Streaming。【参考方案3】:
<webHttpBinding>
   <binding name="TransportSecurity" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
        <security mode="Transport" />
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />
   </binding>

【讨论】:

以上是关于WCF 413 请求实体太大 - 自托管 WebHttpBinding的主要内容,如果未能解决你的问题,请参考以下文章

(413) 使用 WCF 请求实体太大错误

(413) 请求实体太大 - 在 Azure 上上传 Wcf 时

WCF:远程服务器返回错误:(413)请求实体太大[重复]

WCF(413)请求实体太大

具有 30mb 输入字符串的 WCF 服务 - 远程服务器返回错误:(413)请求实体太大

请求实体对于自托管 ASP.Net Web API 来说太大