我有一个返回1000条记录的WCF服务,从数据库中向客户端返回数据。我有一个ASP.NET WCF客户端(我已经在ASP.NET Web应用程序项目中添加了服务引用以使用WCF)。
当我运行客户端应用程序时,会收到以下消息:
传入消息的最大消息大小配额(65536)已超过。要增加配额,请在适当的绑定元素上使用MaxReceivedMessageSize属性。
如何增加消息大小配额?需要什么帮助吗?
我有一个返回1000条记录的WCF服务,从数据库中向客户端返回数据。我有一个ASP.NET WCF客户端(我已经在ASP.NET Web应用程序项目中添加了服务引用以使用WCF)。
当我运行客户端应用程序时,会收到以下消息:
传入消息的最大消息大小配额(65536)已超过。要增加配额,请在适当的绑定元素上使用MaxReceivedMessageSize属性。
如何增加消息大小配额?需要什么帮助吗?
你需要像这样去增加消息大小的配额,在App.config或者Web.config文件中:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</binding>
</basicHttpBinding>
</bindings>
在您的终端配置中使用绑定名称,例如:
...
bindingConfiguration="basicHttp"
...
这些值的理由很简单,它们足够大以容纳大多数消息。您可以调整该数字以适应自己的需求。低默认值基本上是为了防止DOS类型攻击。将其设置为20000000会使分布式DOS攻击变得有效,而64k的默认大小需要非常多的客户端才能压倒大多数服务器。
如果您在使用WCF测试客户端时仍然收到此错误消息,那是因为客户端有单独的MaxBufferSize设置。
要纠正此问题:
将显示可编辑的设置列表,包括MaxBufferSize。
注意:自动生成的代理客户端也默认将MaxBufferSize设置为65536。
如果你正在动态创建你的WCF绑定,这里是代码:
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;
WCF测试客户端有自己的客户端配置文件。
运行测试客户端并向下滚动。如果您双击“配置文件”节点,您将看到XML表示形式。正如您所见,maxReceivedMessageSize
是65536
。
要进行编辑,请右键单击“配置文件”树节点,然后选择使用SvcConfigEditor
进行编辑。当编辑器打开时,展开绑定并双击自动生成的绑定。
您可以在此处编辑所有属性,包括maxReceivedMessageSize
。完成后,单击“文件 - 保存”。
最后,当您回到WCF测试客户端窗口时,单击“工具 - 选项”。
注意:取消选中“启动服务时总是重新生成配置”。
我找到了一种简单的方法
--- 右键单击webconfig或app config文件,点击“编辑WCF配置”,然后转到bingdigs并选择您的服务,在右侧显示的maxReciveMessageSize中输入一个较大的数字 ---
我解决问题的方法如下:
<bindings>
<netTcpBinding>
<binding name="ECMSBindingConfig" closeTimeout="00:10:00" openTimeout="00:10:00"
sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647" portSharingEnabled="true">
<readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" maxDepth="2147483647"
maxBytesPerRead="2147483647" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ECMSServiceBehavior">
<dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceTimeouts transactionTimeout="00:10:00" />
<serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="100"
maxConcurrentInstances="100" />
</behavior>
</serviceBehaviors>
</behaviors>
对于HTTP:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="200"
maxArrayLength="200000000"
maxBytesPerRead="4096"
maxStringContentLength="200000000"
maxNameTableCharCount="16384"/>
</binding>
</basicHttpBinding>
</bindings>
对于TCP:
<bindings>
<netTcpBinding>
<binding name="tcpBinding"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="200"
maxArrayLength="200000000"
maxStringContentLength="200000000"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</binding>
</netTcpBinding>
</bindings>
重要提示:
如果您尝试传递具有许多连接对象(例如:树形数据结构,包含许多对象的列表...)的复杂对象,则无论您如何增加配额,通信都将失败。 在这种情况下,您必须增加包含对象的数量:
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
...
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
maxItemsInObjectGraph
对我来说是一个(快速)解决方案。但是当增加它时,您应该考虑是否更好的解决方案是让您的应用程序以块的形式请求数据,而不是一个可能会耗尽资源的巨大对象图。 - Paul<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IGeocodeService" />
<binding name="BasicHttpBinding_IRouteService" />
</basicHttpBinding>
<customBinding>
<binding name="CustomBinding_IGeocodeService">
<binaryMessageEncoding />
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
<binding name="CustomBinding_IRouteService">
<binaryMessageEncoding />
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"
contract="BingServices.IGeocodeService" name="BasicHttpBinding_IGeocodeService" />
<endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc/binaryHttp"
binding="customBinding" bindingConfiguration="CustomBinding_IGeocodeService"
contract="BingServices.IGeocodeService" name="CustomBinding_IGeocodeService" />
<endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"
contract="BingServices.IRouteService" name="BasicHttpBinding_IRouteService" />
<endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/binaryHttp"
binding="customBinding" bindingConfiguration="CustomBinding_IRouteService"
contract="BingServices.IRouteService" name="CustomBinding_IRouteService" />
</client>
</system.serviceModel>
从我的经验中考虑的另一个重要问题是...
我强烈建议不要将maxBufferPoolSize最大化,因为来自池中的缓冲区直到应用程序域(即应用程序池)回收之前永远不会释放。
高流量期间可能会导致大量内存被使用且永远不会释放。
更多细节请参见:
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_Username" maxReceivedMessageSize="20000000" maxBufferPoolSize="20000000">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" establishSecurityContext="false"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding_Username"
contract="Exchange.Exweb.ExchangeServices.ExchangeServicesGenericProxy.ExchangeServicesType"
name="ServicesFacadeEndpoint" />
</client>