2009-04-24 49 views
74

He encontrado este problema aparentemente común y no he podido resolverlo.Solicitud de servicio web WCF grande que falla con (400) HTTP Bad Request

Si llamo a mi servicio web WCF con un número relativamente pequeño de elementos en un parámetro de matriz (he probado hasta 50), todo está bien.

Sin embargo, si llamo al servicio web con 500 elementos, aparece el error de Solicitud incorrecta.

Curiosamente, he ejecutado Wireshark en el servidor y parece que la solicitud ni siquiera está llegando al servidor: el error 400 se está generando en el lado del cliente.

La excepción es:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request. 

La sección system.serviceModel de mi archivo de configuración de cliente es:

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" 
       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
       allowCookies="false"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:10:00" 
        enabled="false" /> 
       <security mode="None"> 
        <transport clientCredentialType="Windows" proxyCredentialType="None" 
         realm="" /> 
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
         establishSecurityContext="true" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://serviceserver/MyService.svc" 
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService" 
      contract="SmsSendingService.IMyService" name="WSHttpBinding_IMyService" /> 
    </client> 
</system.serviceModel> 

En el lado del servidor, mi archivo web.config tiene la siguiente system.serviceModel sección:

<system.serviceModel> 
    <services> 
     <service name="MyService.MyService" behaviorConfiguration="MyService.MyServiceBehaviour" > 
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyService.MyServiceBinding" contract="MyService.IMyService"> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="MyService.MyServiceBinding"> 
      <security mode="None"></security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="MyService.MyServiceBehaviour"> 
       <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
       <serviceMetadata httpGetEnabled="true"/> 
       <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
       <serviceDebug includeExceptionDetailInFaults="true"/> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

He looked at un fairly largenumber de answers a this question con no success.

¿Alguien me puede ayudar con esto?

+0

Si no está llegando al servidor, tal vez haya algún problema con los datos que se envían. Tal vez hay algunos personajes ilegales en la solicitud? Suponiendo también que esto es SOAP –

+1

, ¿ha intentado configurar todos sus atributos 'max' (por ejemplo, maxReceivedMessageSize ...) a un número realmente alto? – mundeep

+0

Sí, es JABÓN. Y no debería haber nada de malo en la solicitud, como dije, todo funciona bien para hasta 50 elementos generados con la misma aplicación ... – Damovisa

Respuesta

107

Intenta establecer maxReceivedMessageSize en el servidor también, p. 4 MB:

<binding name="MyService.MyServiceBinding" 
      maxReceivedMessageSize="4194304"> 

La razón principal por defecto (65535 creo) es tan baja es reducir el riesgo de ataques de denegación de servicio (DoS). Debe configurarlo más grande que el tamaño máximo de solicitud en el servidor y el tamaño máximo de respuesta en el cliente. Si se encuentra en un entorno Intranet, el riesgo de ataques DoS es probablemente bajo, por lo que probablemente sea seguro usar un valor mucho más alto de lo que espera.

Por cierto un par de consejos para solucionar problemas de conexión a los servicios WCF:

  • habilitar el seguimiento en el servidor como se describe en this MSDN article.

  • Utilice una herramienta de depuración HTTP como Fiddler en el cliente para inspeccionar el tráfico HTTP.

+1

Increíble, eso es todo. ¡Gracias por tu respuesta! – Damovisa

+2

¡Gracias por el enlace para habilitar el seguimiento! –

+2

Traté de hacer lo mismo en mi extremo, pero no pude probar el éxito. – Kangkan

4

Podría ser útil depurar el cliente, desactivar Herramientas \ Opciones \ Depuración \ General \ 'Habilitar solo mi código', hacer clic en Depurar \ Excepciones \ 'atrapar todas las excepciones de primera oportunidad' para las excepciones de CLR administradas, y ver si hay una excepción debajo del capó en el cliente antes de la excepción de protocolo y antes de que el mensaje llegue al cable. (Mi suposición sería algún tipo de falla de serialización.)

+0

Lo intentaré, gracias :) – Damovisa

7

También conseguía esta cuestión también sin embargo ninguno de los anteriores trabajado para mí, ya que estaba usando una unión (por BinaryXML) personalizado después de un largo tiempo de excavación he encontrado la respuesta aquí: -

Sending large XML from Silverlight to WCF

Como estoy usando un customBinding, la maxReceivedMessageSize tiene que ser establecido en el elemento httpTransport bajo el elemento de unión en el web.config:

<httpsTransport maxReceivedMessageSize="4194304" /> 
+0

Muchas gracias :-) –

7

Por lo que vale, una consideración adicional al usar .NET 4.0 es que si no se encuentra un punto final válido en su configuración, se creará y usará automáticamente un punto final predeterminado.

El punto final predeterminado utilizará todos los valores predeterminados por lo que si cree que tiene una configuración de servicio válida con un valor grande para maxReceivedMessageSize etc., pero hay algún problema con la configuración, aún obtendrá 400 Bad Request desde el punto final predeterminado se crearía y usaría.

Esto se hace de forma silenciosa por lo que es difícil de detectar. Verá mensajes a este efecto (por ejemplo, 'No se encontró un punto final para el servicio, creando un punto final predeterminado' o similar) si activa el rastreo en el servidor, pero no hay otra indicación (que yo sepa). También

+0

@ user469104: Muy buen consejo. Gracias. ¿Hay alguna manera de forzar al servidor a usar un punto final declarado a mano sin sobrescribir el ServiceHost predeterminado? – RaSor

3

Sólo quiero señalar

Aparte de MaxRecivedMessageSize, hay atributos bajo ReaderQuotas, que puede pegarle número de elementos en lugar de limitar el límite de tamaño. El enlace de MSDN es here

5

En el servidor en .NET 4.0 en web.config también necesita cambiar el enlace predeterminado. Establezca los siguientes 3 parms:

< basicHttpBinding> 
    < !--http://www.intertech.com/Blog/post/NET-40-WCF-Default-Bindings.aspx 
    - Enable transfer of large strings with maxBufferSize, maxReceivedMessageSize and maxStringContentLength 
    --> 
    < binding **maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"**> 
     < readerQuotas **maxStringContentLength="2147483647"**/>    
    < /binding> 
+0

Gracias. Estaba buscando la convención predeterminada para enlaces. – JTew

+0

Gracias :) Este fue mi problema. –

3

Encontré la respuesta al problema de la solicitud incorrecta 400.

Era la configuración de enlace de servidor predeterminada. Debería agregar a la configuración predeterminada del servidor y del cliente.

binding name = "" openTimeout = "00:10:00" closeTimeout = "00:10:00" receiveTimeout = "00:10:00" sendTimeout = "00:10:00" maxReceivedMessageSize = "2147483647" maxBufferPoolSize = "2147483647" MaxBufferSize = "2147483647">

4

también puede activar el registro de WCF para obtener más información sobre el error original. Esto me ayudó a resolver este problema.

Añadir lo siguiente a su web.config, se guarda el registro en C: \ log \ Traces.svclog

<system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
        switchValue="Information, ActivityTracing" 
        propagateActivity="true"> 
      <listeners> 
       <add name="traceListener" 
        type="System.Diagnostics.XmlWriterTraceListener" 
        initializeData= "c:\log\Traces.svclog" /> 
      </listeners> 
     </source> 
    </sources> 
</system.diagnostics> 
+1

A veces las respuestas más simples son las mejores. En mi caso, descubrí que estaba devolviendo un objeto Stream nulo en una llamada de respuesta de transmisión. El svclog resolvió esto en segundos. Gracias. –

1

En mi caso, que no estaba funcionando incluso después de intentar todas las soluciones y establecer todos los límites a max. Finalmente, descubrí que un módulo de filtrado Microsoft IIS Url Scan 3.1 se instaló en IIS/sitio web, que tienen su propio límite para rechazar las solicitudes entrantes según el tamaño del contenido y devolver la "página 404 No encontrada".

Su límite se puede actualizar en el archivo %windir%\System32\inetsrv\urlscan\UrlScan.ini configurando MaxAllowedContentLength en el valor requerido.

Por ej.tras permitirá hasta 300 mb solicita

MaxAllowedContentLength = 314572800

esperan que ayude a alguien!

Cuestiones relacionadas