关于.net:WCF – 如何增加邮件大小配额

WCF - How to Increase Message Size Quota

我有一个wcf服务,它将1000条记录从数据库返回到客户机。我有一个ASP.NET WCF客户端(我在ASP.NET Web应用程序项目中添加了服务引用以使用WCF)。

运行客户端应用程序时,我收到以下消息:

The maximum message size quota for incoming messages (65536) has been
exceeded. To increase the quota, use
the MaxReceivedMessageSize property on
the appropriate binding element.

有什么帮助吗?如何增加邮件大小配额?


在app.config或web.config文件中,您将需要类似这样的内容来增加邮件大小配额:

1
2
3
4
5
6
7
8
9
10
11
12
<bindings>
    <basicHttpBinding>
        <binding name="basicHttp" allowCookies="true"
                 maxReceivedMessageSize="20000000"
                 maxBufferSize="20000000"
                 maxBufferPoolSize="20000000">
            <readerQuotas maxDepth="32"
                 maxArrayLength="200000000"
                 maxStringContentLength="200000000"/>
        </binding>
    </basicHttpBinding>
</bindings>

并在端点配置中使用绑定名称,例如

1
2
3
...
bindingConfiguration="basicHttp"
...

这些值的理由很简单,它们足够大以容纳大多数消息。你可以根据你的需要调整这个数字。低默认值基本上是为了防止DOS类型的攻击。使其20000000将允许分布式DOS攻击有效,默认大小64K将需要大量客户端来压倒大多数服务器。


如果在使用WCF测试客户机时仍然收到此错误消息,那是因为客户机有一个单独的MaxBufferSize设置。

要更正此问题:

  • 右键单击树底部的配置文件节点
  • 选择使用svcconfigeditor编辑
  • 将显示可编辑设置的列表,包括MaxBufferSize。

    注意:默认情况下,自动生成的代理客户端还将MaxBufferSize设置为65536。


    如果要动态创建WCF绑定,请使用以下代码:

    1
    2
    3
    4
    5
    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表示。如你所见,maxReceivedMessageSize65536

    要编辑此文件,请右键单击配置文件树节点,然后选择使用SvcConfigEditor编辑。当编辑器打开时,展开绑定并双击自动生成的绑定。

    您可以在这里编辑所有属性,包括maxReceivedMessageSize。完成后,单击文件-保存。

    最后,当您回到WCF测试客户端窗口时,单击工具-选项。

    注意:在启动服务时取消选中总是重新生成配置。


    我找到了简单的方法

    --- right click the webconfig or app config file and click EDIT WCF CONFIGURATION and got to bingdigs ans select yore service and right
    side show maxReciveMessageSize give a large number ---


    我在我的项目中使用calculateRoute()解决了必应地图WPF的问题。在我的例子中,解决方案是在"custombinding"部分的属性"httptransport"上设置maxReceivedMessageSize和maxReceivedMessageSize。

    我在applications.config文件中设置。myapp.config)此配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <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>


    我解决这个问题……如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        <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>


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <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>


    对我来说,我所要做的就是将maxReceivedMessageSize="2147483647"添加到客户机app.config中。服务器保持原样。


    根据我的经验,还有一件重要的事情要考虑。

    我强烈建议不要最大化MaxBufferPoolSize,因为在应用程序域(即应用程序池)回收之前,永远不会释放池中的缓冲区。

    一段时间的高流量可能会导致大量内存被使用,并且永远不会释放。

    详细信息如下:

    • https://stackoverflow.com/a/19953113/496676
    • http://andriybuday.com/2011/08/wcf-configuration-caused-memory-leaks.html

    对于HTTP:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <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>

    重要:

    如果尝试传递具有多个连接对象的复杂对象(例如:树数据结构、具有多个对象的列表…),则无论如何增加配额,通信都将失败。在这种情况下,必须增加包含对象的计数:

    1
    2
    3
    4
    5
    6
    7
    8
    <behaviors>
      <serviceBehaviors>
        <behavior name="NewBehavior">
          ...
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>


    不要忘记将考虑执行入口点的app.config,而不是类库项目中管理Web服务调用(如果有)的app.config。

    例如,如果在运行单元测试时出现错误,则需要在测试项目中设置适当的配置。


    在web.config上使用此设置时出现此错误

    1
    System.ServiceModel.ServiceActivationException

    我设置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
          <service name="idst.Controllers.wcf.Service_Talks">
        <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_TalksAspNetAjaxBehavior"
          binding="webHttpBinding" contract="idst.Controllers.wcf.Service_Talks" />
      </service>
      <service name="idst.Controllers.wcf.Service_Project">
        <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_ProjectAspNetAjaxBehavior"
          binding="basicHttpBinding" bindingConfiguration="" bindingName="largBasicHttp"
          contract="idst.Controllers.wcf.Service_Project" />
      </service>
    </services>

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