WCF - Cómo aumentar la cuota de tamaño de mensaje

454

Tengo un servicio WCF que devuelve 1000 registros de la base de datos al cliente. Tengo un cliente ASP.NET WCF (he agregado referencia de servicio en el proyecto de aplicación web asp.net para consumir WCF).

Recibo el siguiente mensaje cuando ejecuto la aplicación cliente:

Se ha excedido la cuota máxima de tamaño de mensaje para mensajes entrantes (65536). Para aumentar la cuota, use la propiedad MaxReceivedMessageSize en el elemento de enlace apropiado.

¿Alguna ayuda? ¿Cómo aumentar la cuota de tamaño de mensaje?

bugBurger
fuente
Tuve el mismo problema, pero acabo de recibir un error de red hostil 400, pero la solución fue el tamaño del mensaje ..
Sr. W
2
Resolví el problema utilizando los pasos mencionados en [el enlace] [1] [1]: stackoverflow.com/questions/7476853/…
Ram
¿Por qué está tan bajo por defecto? ¿Seguridad?
Coops
@Coops para la seguridad de hecho. Al establecer una cuota en los mensajes, por ejemplo, los ataques DDOS son (al menos un poco) más difíciles de ejecutar.
Peter van Kekem el

Respuestas:

608

Querrá algo como esto para aumentar las cuotas de tamaño de mensaje, en el archivo App.config o 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>

Y use el nombre del enlace en su configuración de punto final, por ejemplo

...
bindingConfiguration="basicHttp"
...

La justificación de los valores es simple, son lo suficientemente grandes como para acomodar la mayoría de los mensajes. Puede ajustar ese número para satisfacer sus necesidades. El valor predeterminado bajo está básicamente allí para evitar ataques de tipo DOS. Convertirlo en 20000000 permitiría que un ataque distribuido de DOS sea efectivo, el tamaño predeterminado de 64k requeriría una gran cantidad de clientes para dominar la mayoría de los servidores en estos días.

Nate
fuente
20
Gracias ... Este cambio debe hacerse en el archivo web.config de la aplicación cliente.
bugBurger
8
Es posible que también deba cambiarlo en el servidor; en caso de que necesite enviar un conjunto de datos grande como parámetro a un Método WCF.
Nate
99
Es suficientemente grande para acomodar la mayoría de los mensajes. Puede ajustar ese número para satisfacer sus necesidades. Básicamente está ahí para prevenir ataques de tipo DOS. Por lo que es 20000000 permitiría un ataque DoS distribuido para ser eficaz, el tamaño predeterminado de 64k requeriría un gran número de clientes para dominar a la mayoría de los servidores de estas day.s
Nate
18
Para otros interesados, leí en otro blog que el tamaño máximo es 2147483647. 20000000 es un poco más pequeño que este número, por lo que tiene sentido usar el número más pequeño con el que pueda salirse sin interrumpir el servicio.
proudgeekdad
55
@Slauma Tendría que cambiarse en el servidor si ese parámetro entrante era demasiado grande; de lo contrario (y más probable) el cambio debe realizarse en el archivo de configuración del cliente, ya que es la respuesta del servicio (no su parámetro) lo que es demasiado grande.
Nate
155

Si aún recibe este mensaje de error mientras usa el Cliente de prueba WCF, es porque el cliente tiene una configuración MaxBufferSize separada .

Para corregir el problema:

  1. Haga clic derecho en el nodo del archivo de configuración en la parte inferior del árbol
  2. Seleccione Editar con SvcConfigEditor

Aparecerá una lista de configuraciones editables, incluido MaxBufferSize.

Nota: Los clientes proxy generados automáticamente también establecen MaxBufferSize en 65536 de forma predeterminada.

Michael Rodrigues
fuente
8
¿Por qué, oh, por qué siempre me olvido de esto? +1
James Skemp
99
En vs2013, SvcConfigEditor se reemplaza con Editar configuración WCF si la gente lo está buscando.
ZoomVirus
¿No puede encontrar SVCconfigEditor?
Arul Sidthan
Lo encontrará en la carpeta Enlaces, haga clic en el enlace para el servicio y está allí.
Sameer Alibhai
Si su archivo de configuración se genera automáticamente, absolutamente debe hacerlo de esta manera. Cada vez que actualice su referencia, se volverá a generar la aplicación.config, y deberá volver a cambiarla manualmente. Sin embargo, si lo cambia VS, los nuevos cambios se adaptarán a la configuración que haya elegido.
kingfrito_5005
104

Si está creando sus enlaces WCF dinámicamente, aquí está el código que debe usar:

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
fuente
Puede usarlo inicializar. Claramente puedes usarlo como método constructor.
aemre
45

El cliente de prueba WCF tiene su propia configuración de cliente.

Ejecute el cliente de prueba y desplácese hasta la parte inferior. Si hace doble clic en el nodo Archivo de configuración, verá la representación XML. Como puedes ver el maxReceivedMessageSizees 65536.

Para editar esto, haga clic derecho en el nodo del árbol del archivo de configuración y seleccione Editar con SvcConfigEditor. Cuando se abra el editor, expanda Enlaces y haga doble clic en el enlace que se generó automáticamente.

Puede editar todas las propiedades aquí, incluidas maxReceivedMessageSize. Cuando haya terminado, haga clic en Archivo - Guardar .

Por último, cuando vuelva a la ventana de WCF Test Client, haga clic en Herramientas - Opciones .

NOTA : Desmarque la configuración Regenerar siempre al iniciar servicios .

Jodee Dex Page
fuente
2
¡Probablemente la mejor respuesta aquí!
Haris
3
votar debido a la nota para desmarcar la Always regenerate configopción.
furioso
La solución más simple en mi opinión. Me ahorró un poco de dolor de cabeza.
Jared Beach
En vs2013, SvcConfigEditor se reemplaza con Editar configuración WCF si la gente lo está buscando.
ZoomVirus
Gracias. ¡Me he estado rompiendo la cabeza por un tiempo, cambiando la configuración del servidor una y otra vez, cuando el problema estaba en la configuración de Test Client!
Fahad
24

Encontre el camino facil

--- haga clic con el botón derecho en el archivo de configuración web o de configuración de la aplicación y haga clic en EDITAR CONFIGURACIÓN WCF y llegue a bingdigs y seleccione el servicio anterior y el lado derecho muestre maxReciveMessageSize para dar un gran número ---

NC64
fuente
2
Fue una gran respuesta, no sabía que puedo editar desde aquí, gracias
albert sh
8

Resuelvo el problema ... de la siguiente manera

    <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
fuente
20
¿Cómo difiere esto de mi solución? ¿Además de incluir todas las partes irrelevantes de su configuración, así como las partes relevantes, y eligió el valor máximo posible en lugar de los 200 m que elegí?
Nate
3
El contexto también es bueno ... ¿tal vez estas dos respuestas podrían fusionarse?
Jeff
1
¿Esa configuración se configura en el servidor o el cliente?
John Kenedy
8

Resolví mi problema en Bing Maps WPF en mi proyecto usando CalculateRoute (). La solución en mi caso fue configurar maxReceivedMessageSize y maxReceivedMessageSize en el atributo "httpTransport" para la sección "customBinding".

Configuré en el archivo aplicaciones.config (es. MyApp.config) esta configuración:

<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
fuente
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
fuente
Genial para publicar tu respuesta. Es importante que el valor "bindingConfiguration" coincida con el nombre del enlace. En su ejemplo "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:

Si intenta pasar un objeto complejo que tiene muchos objetos conectados (por ejemplo: una estructura de datos de árbol, una lista que tiene muchos objetos ...), la comunicación fallará sin importar cómo haya aumentado las Cuotas. En tales casos, debe aumentar el recuento de objetos que contienen:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
Jacob
fuente
El maxItemsInObjectGraphera la solución (rápida) para mí. Pero cuando aumente esto, debe pensar si la mejor solución es que su aplicación solicite datos en fragmentos, en lugar de un gráfico de objeto enorme que puede agotar los recursos.
Paul
6

Para mí, todo lo que tenía que hacer es agregar maxReceivedMessageSize="2147483647"al cliente app.config. El servidor se dejó intacto.

ashilon
fuente
5

Otra cosa importante a considerar desde mi experiencia ...

Recomiendo encarecidamente NO maximizar maxBufferPoolSize, porque los búferes del grupo nunca se liberan hasta que el dominio de la aplicación (es decir, el grupo de aplicaciones) se recicla.

Un período de alto tráfico podría causar que se use mucha memoria y nunca se libere.

Más detalles aquí:

Valerio Gentile
fuente
3

No olvide que se considerará la aplicación.config del punto de entrada de ejecución, no la del proyecto de biblioteca de clase que administra las llamadas de servicio web si hay una.

Por ejemplo, si obtiene el error mientras ejecuta la prueba de la unidad, debe configurar la configuración adecuada en el proyecto de prueba.

Charla
fuente
0

Recibí este error al usar esta configuración en web.config

System.ServiceModel.ServiceActivationException

establezco configuraciones 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
fuente
44
Entonces, resolvió su problema utilizando la respuesta de Nate y luego la publicó como propia. No es genial
arcain
La respuesta de @arcain Nates fue muy genérica, utilizando nombres y números de acciones que se pueden esperar con frecuencia. Esta respuesta no fue robada, es simplemente la respuesta correcta. Como solo hay una respuesta correcta, estaba destinada a repetirse.
kingfrito_5005
@ kingfrito_5005 La respuesta "correcta" ya estaba aquí cuando el contestador publicó esto. Él claramente levantó el bindingselemento de Nate y lo volvió a publicar como parte de su respuesta. Esos 2000000valores son bastante distintos.
arcain
@arcain, no estoy de acuerdo con los valores estándar, mi empresa también los usa en nuestros elementos vinculantes.
kingfrito_5005