WCF - Como aumentar a cota de tamanho de mensagem

454

Eu tenho um serviço WCF que retorna 1000 registros do banco de dados para o cliente. Eu tenho um cliente ASP.NET WCF (eu adicionei referência de serviço no projeto de aplicativo da web asp.net para consumir o WCF).

Recebo a seguinte mensagem quando executo o aplicativo cliente:

A cota máxima do tamanho das mensagens recebidas (65536) foi excedida. Para aumentar a cota, use a propriedade MaxReceivedMessageSize no elemento de ligação apropriado.

Qualquer ajuda? Como aumentar a cota do tamanho da mensagem?

bugBurger
fonte
Eu tive o mesmo problema, mas eu só tenho um erro de rede hostil 400, mas a solução era o thingie tamanho da mensagem ..
Sr. W
2
Eu resolvi o problema usando as etapas mencionadas em [link] [1] [1]: stackoverflow.com/questions/7476853/...
Ram
Por que está definido tão baixo por padrão? Segurança?
Coops
@ Cooper para segurança de fato. Ao definir uma cota nas mensagens, por exemplo, os ataques DDOS são (pelo menos um pouco) mais difíceis de executar.
Peter van Kekem

Respostas:

608

Você deseja algo assim para aumentar as cotas de tamanho da mensagem, no arquivo App.config ou 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>

E use o nome da ligação na sua configuração do terminal, por exemplo

...
bindingConfiguration="basicHttp"
...

A justificativa para os valores é simples, eles são suficientemente grandes para acomodar a maioria das mensagens. Você pode ajustar esse número para atender às suas necessidades. O baixo valor padrão está basicamente lá para impedir ataques do tipo DOS. Para 20000000, seria eficaz um ataque distribuído do DOS; o tamanho padrão de 64k exigiria que um número muito grande de clientes sobrecarregasse a maioria dos servidores atualmente.

Nate
fonte
20
Obrigado .. Essa alteração precisa ser feita no arquivo web.config do aplicativo cliente.
BugBurger 19/05/09
8
Você também pode precisar alterá-lo no servidor - caso precise enviar um grande conjunto de dados como parâmetro para um Método WCF.
Nate
9
É suficientemente grande para acomodar a maioria das mensagens. Você pode ajustar esse número para atender às suas necessidades. Está basicamente lá para impedir ataques do tipo DOS. Tornando-20000000 permitiria um ataque DoS distribuído para ser eficaz, o tamanho padrão de 64k exigiria um número muito grande de clientes para dominar a maioria dos servidores estas day.s
Nate
18
Para outras pessoas interessadas, li em outro blog que o tamanho máximo é 2147483647. 20000000 é um pouco menor que esse número; portanto, usar o número menor com o qual você pode se dar bem sem interromper o serviço faz sentido.
Proudseekdad 7/10
5
@ Sluma Seria necessário alterar o servidor se esse parâmetro recebido fosse muito grande; caso contrário (e mais provável), a alteração precisará ser feita no arquivo de configuração do cliente, pois é a resposta do serviço (não seu parâmetro) que é muito grande.
Nate
155

Se você ainda receber essa mensagem de erro enquanto estiver usando o WCF Test Client, é porque o cliente possui uma configuração MaxBufferSize separada .

Para corrigir o problema:

  1. Clique com o botão direito do mouse no nó Arquivo de configuração na parte inferior da árvore
  2. Selecione Editar com SvcConfigEditor

Uma lista de configurações editáveis ​​será exibida, incluindo MaxBufferSize.

Nota: Os clientes proxy gerados automaticamente também configuram MaxBufferSize como 65536 por padrão.

Michael Rodrigues
fonte
8
Por que oh, por que eu sempre esqueço disso? 1
James Skemp
9
No vs2013, o SvcConfigEditor é substituído pela configuração Editar WCF, se as pessoas estiverem procurando.
ZoomVirus
Não é possível encontrar o SVCconfigEditor?
Arul Sidthan
Você o encontrará na pasta Ligações, clique na ligação do serviço e ela está lá.
Sameer Alibhai
Se o seu arquivo de configuração é gerado automaticamente, você deve fazê-lo dessa maneira. Sempre que você atualizar sua referência, ela regenera o app.config e será necessário alterá-la manualmente novamente. Se você alterar o VS, as novas alterações acomodarão as configurações que você escolheu.
23815
104

Se você estiver criando suas ligações WCF dinamicamente, aqui está o código a ser usado:

BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;
Bharath K
fonte
Você pode usá-lo inicializar. Claramente, você pode usá-lo como método construtor.
aemre
45

O cliente de teste do WCF possui sua própria configuração de cliente.

Execute o cliente de teste e role para baixo. Se você clicar duas vezes no nó Arquivo de configuração, verá a representação XML. Como você pode ver, maxReceivedMessageSizeé65536 .

Para editar isso, clique com o botão direito do mouse no nó da árvore Config File e selecione Edit With SvcConfigEditor . Quando o editor abrir, expanda Ligações e clique duas vezes na ligação que foi gerada automaticamente.

Você pode editar todas as propriedades aqui, incluindo maxReceivedMessageSize. Quando terminar, clique em Arquivo - Salvar .

Por fim, quando voltar à janela Cliente de Teste do WCF, clique em Ferramentas - Opções .

NOTA : Desmarque a opção Sempre gerar novamente a configuração ao iniciar serviços .

Jodee Dex Page
fonte
2
Provavelmente a melhor resposta aqui!
Haris
3
voto positivo devido à nota para desmarcar a Always regenerate configopção.
furier
Mais simples resolver na minha opinião. Me salvou um pouco de dor de cabeça.
Jared Praia
No vs2013, o SvcConfigEditor é substituído pela configuração Editar WCF, se as pessoas estiverem procurando.
ZoomVirus
Obrigado. Estou quebrando a cabeça há um tempo, mudando a configuração do servidor repetidas vezes, quando o problema estava com a configuração do Cliente de Teste!
Fahad
24

Eu achei o caminho mais fácil

--- clique com o botão direito do mouse no arquivo webconfig ou de configuração do aplicativo e clique em EDITAR CONFIGURAÇÃO DO WCF e acesse o bingdigs ans selecione o serviço anterior e o lado direito mostre maxReciveMessageSize dê um número grande ---

NC64
fonte
2
Foi uma grande resposta, eu não sabia que eu possa editar a partir daqui, Graças
albert sh
8

Eu resolvo o problema ... da seguinte forma

    <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>
Rajesh Kuamr Chekuri
fonte
20
Como isso difere da minha solução? Além de incluir todas as partes irrelevantes da sua configuração, bem como as partes relevantes, e você escolheu o valor máximo possível em vez dos 200m que eu escolhi?
Nate
3
O contexto também é bom ... talvez essas duas respostas possam ser mescladas?
Jeff
1
essa configuração deve ser configurada no servidor ou cliente?
John Kenedy
8

Resolvi meu problema no Bing Maps WPF no meu projeto usando CalculateRoute (). A solução no meu caso foi definir maxReceivedMessageSize e maxReceivedMessageSize no atributo "httpTransport" para a seção "customBinding".

Defino no arquivo applications.config (es. MyApp.config) esta configuração:

<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>
Francesco Germinara
fonte
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>

Hemant Soni
fonte
Ótimo para postar sua resposta. É importante que o valor "bindingConfiguration" corresponda ao nome da ligação. No seu exemplo "wsHttpBinding_Username".
Bruno Bieri
6

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

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

IMPORTANTE:

Se você tentar passar um objeto complexo que possui muitos objetos conectados (por exemplo: uma estrutura de dados em árvore, uma lista que possui muitos objetos ...), a comunicação falhará, independentemente de como você aumentou as cotas. Nesses casos, você deve aumentar a contagem de objetos contidos:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
Jacob
fonte
Essa maxItemsInObjectGraphfoi a solução (rápida) para mim. Mas, ao aumentar isso, você deve pensar se a melhor solução é para seu aplicativo solicitar dados em partes, em oposição a um enorme gráfico de objetos que pode sobrecarregar os recursos.
Paul
6

Para mim, tudo que eu precisava fazer era adicionar maxReceivedMessageSize="2147483647"ao cliente app.config. O servidor permaneceu intocado.

ashilon
fonte
5

Outra coisa importante a considerar da minha experiência ..

Eu recomendaria fortemente NÃO maximizar o maxBufferPoolSize, porque os buffers do pool nunca são liberados até que o domínio do aplicativo (ou seja, o Application Pool) seja reciclado.

Um período de tráfego intenso pode fazer com que muita memória seja usada e nunca seja liberada.

Mais detalhes aqui:

Valerio Gentile
fonte
3

Não esqueça que o app.config do ponto de entrada de execução será considerado, e não o projeto da biblioteca de classes que gerencia as chamadas de serviços da Web, se houver.

Por exemplo, se você receber o erro ao executar o teste de unidade, precisará definir a configuração apropriada no projeto de teste.

Entalhe
fonte
0

Eu recebi esse erro ao usar essas configurações no web.config

System.ServiceModel.ServiceActivationException

eu defino configurações como esta:

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

FARHAD AFSAR
fonte
4
Então, você resolveu o problema usando a resposta de Nate e a postou como sua. Não é legal.
Arcain
A resposta de @arcain Nates foi muito genérica, usando nomes e números de ações que podem surgir com frequência. Esta resposta não foi roubada, é simplesmente a resposta certa. Como existe apenas uma resposta correta, ela deve ser repetida.
kingfrito_5005
@ kingfrito_5005 A resposta "correta" já estava aqui quando o respondente postou isso. Ele claramente levantou o bindingselemento de Nate e o republicou como parte de sua resposta. Esses 2000000valores são bem distintos.
arcain 24/07/2015
@Arain, eu discordo que esses são valores muito padrão, minha empresa os usa também em nossos elementos vinculativos.
kingfrito_5005