WCF-如何增加邮件大小配额


453

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

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

超出了传入消息的最大消息大小配额(65536)。要增加配额,请在适当的绑定元素上使用MaxReceivedMessageSize属性。

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


我遇到了同样的问题,但是我遇到了一个不友好的网络错误400,但是解决方案是消息大小的东西。–
W W

2
我通过使用[链接] [1] [1]中提到的步骤解决了该问题:stackoverflow.com/questions/7476853/…–
拉姆

为什么默认将其设置为如此低?安全?
合作社

@Coops确实是安全的。通过为邮件设置配额,例如,DDOS攻击(至少一点)很难执行。
彼得·凡·凯姆

Answers:


607

您需要在App.configWeb.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将需要大量的客户端来使如今的大多数服务器超负荷运行。


20
谢谢..此更改需要在客户端应用程序的web.config文件中进行。
bugBurger

8
您可能还需要在服务器上进行更改-如果需要将大型数据集作为参数发送给WCF方法,则可能需要更改它。
内特

9
它足够大以容纳大多数消息。您可以调整该数字以满足您的需求。基本上可以防止DOS类型的攻击。将其设置为2000万将使分布式DOS攻击有效,默认大小64k将需要大量客户端来使今天的大多数服务器超负荷。s
Nate

18
对于其他感兴趣的人,我在另一个博客上读到,最大大小为2147483647。20000000比这个数字小一点,因此使用最小的数字可以在不中断服务的情况下摆脱困境。
感到骄傲

5
@Slauma如果传入的参数太大,则需要在服务器上进行更改;否则(并且更有可能)需要在客户端配置文件中进行更改,这是因为服务的响应(而不是其参数)太大。
Nate

155

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

要解决此问题,请执行以下操作:

  1. 右键单击树底部的“ 配置文件”节点
  2. 选择使用SvcConfigEditor编辑

将显示可编辑设置的列表,包括MaxBufferSize。

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


8
为什么哦,为什么我总是忘记这一点?+1
James Skemp

9
在vs2013上,如果人们正在寻找,则SvcConfigEditor将替换为Edit WCF配置。
ZoomVirus 2014年

找不到SVCconfigEditor?
Arul Sidthan 2014年

您将在Bindings文件夹下找到它,单击服务绑定,它就在其中。
Sameer Alibhai 2015年

如果您的配置文件是自动生成的,则绝对应采用这种方式。每当您更新参考时,它将重新生成app.config,并且您将不得不再次手动更改它。如果您更改了VS,则新更改将适应您选择的设置。
kingfrito_5005

104

如果要动态创建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;

您可以使用它进行初始化。显然,您可以将其用作构造函数方法。
aemre

45

WCF测试客户端有它自己的客户端配置。

运行测试客户端,然后滚动到底部。如果双击“配置文件”节点,将看到XML表示形式。如您所见,maxReceivedMessageSize65536

要进行编辑,请右键单击“配置文件”树节点,然后选择“编辑方式” SvcConfigEditor。当编辑器打开时,展开“绑定”,然后双击自动生成的绑定。

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

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

注意在启动服务时,取消选中始终重新生成配置


2
可能是这里最好的答案!
哈里斯2014年

3
由于有注释,请取消选中该Always regenerate config选项。
2014年

我认为最简单的解决方法。救了我一些头疼。
Jared Beach

在vs2013上,如果人们正在寻找,则SvcConfigEditor将替换为Edit WCF配置。
ZoomVirus 2014年

谢谢。当问题出在测试客户端配置上时,我已经花了一段时间了,一次又一次地更改服务器配置!
Fahad

24

我找到了简单的方法

---右键单击webconfig或应用程序配置文件,然后单击EDIT WCF CONFIGURATION,然后转到bingdigs an select yore服务,并在右侧显示maxReciveMessageSize给出大量-


2
这是一个很好的答案,我不知道可以从这里进行编辑,谢谢
albert sh

8

我解决问题...如下

    <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>

20
这与我的解决方案有何不同?除了您包括配置的所有不相关部分以及相关部分之外,您选择了最大可能值而不是我选择的200m?
Nate

3
上下文也很好...也许这两个答案可以合并?
杰夫,

1
该设置是在服务器还是客户端中配置?
约翰·肯尼迪

8

我使用CalculateRoute()解决了我项目上Bing Maps WPF的问题。在我的情况下,解决方案是在“ customBinding”部分的属性“ httpTransport”上设置maxReceivedMessageSize和maxReceivedMessageSize。

我在apps.config文件(例如myApp.config)中设置了以下配置:

<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>

6

<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>


非常适合发布您的答案。重要的是“ bindingConfiguration”值必须与绑定名称匹配。在您的示例“ wsHttpBinding_Username”中。
Bruno Bieri 2015年

6

对于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对我来说是(快速)解决方案。但是,当增加此数量时,您应该考虑更好的解决方案是否是应用程序以块为单位请求数据,而不是可能会占用大量资源的庞大对象图。
保罗

6

对我来说,我要做的就是将其添加maxReceivedMessageSize="2147483647"到客户端app.config中。服务器保持不变。



3

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

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


0

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

System.ServiceModel.ServiceActivationException

我这样设置:

      <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>


4
因此,您使用Nate的答案解决了问题,然后将其发布为自己的问题。不酷
阿卡因

@arcain Nates的回答非常通用,使用的股票名称和编号可能会经常出现。这个答案没有被偷,只是正确的答案。由于只有一个正确的答案,因此必定会被重复。
kingfrito_5005

@ kingfrito_5005当回答者发布此答案时,“正确”答案已在此处。他很明显地抬起了Nate的bindings元素,并将其重新发布作为他回答的一部分。这些2000000价值观非常不同。
arcain 2015年

@arcain,我不同意这些是非常标准的值,我的公司也在我们的绑定元素中使用它们。
kingfrito_5005
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.