2009-09-17 34 views
7

He investigado el código 400 - BadRequest durante las últimas dos horas. Muchas sugerencias hacen para garantizar que el atributo bindingConfiguration esté configurado correctamente y, en mi caso, sí lo está.No se puede establecer maxReceivedMessageSize a través de web.config

Ahora, necesito su ayuda antes de destruir el edificio que estoy en :-)

Tengo un servicio de WCF Restfull (muy ligero, el uso de este recurso para la inspiración: http://msdn.microsoft.com/en-us/magazine/dd315413.aspx), que (por ahora) acepta una XmlElement (POX) proporcionado a través del verbo POST.

Actualmente, SOLO estoy usando el creador de solicitudes de Fiddler antes de implementar un cliente verdadero (ya que se trata de entornos mixtos).

Cuando hago esto para XML menor que 65K, funciona bien - más grande, arroja esta excepción: Se ha excedido la cuota máxima de tamaño de mensaje para los mensajes entrantes (65536). Para aumentar la cuota, use la propiedad MaxReceivedMessageSize en el elemento de enlace apropiado.

Aquí está mi archivo web.config (que incluso incluí la etiqueta para el cliente (tiempos desesperados)!):

<system.web> 
    <httpRuntime maxRequestLength="1500000" executionTimeout="180"/> 
    </system.web> 
    <system.serviceModel> 
    <diagnostics> 
     <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" /> 
    </diagnostics> 
    <bindings> 
     <webHttpBinding> 
     <binding name="WebHttpBinding" maxReceivedMessageSize="1500000" maxBufferPoolSize="1500000" maxBufferSize="1500000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00"> 
      <readerQuotas maxStringContentLength="1500000" maxArrayLength="1500000" maxBytesPerRead="1500000" /> 
      <security mode="None"/> 
     </binding> 
     </webHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="" binding="webHttpBinding" bindingConfiguration="WebHttpBinding" contract="Commerce.ICatalogue"/> 
    </client> 
    <services> 
     <service behaviorConfiguration="ServiceBehavior" name="Catalogue"> 
     <endpoint address="" 
        behaviorConfiguration="RestFull" 
        binding="webHttpBinding" 
        bindingConfiguration="WebHttpBinding" 
        contract="Commerce.ICatalogue" /> 
     <!-- endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/--> 
     </service> 
    </services> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="RestFull"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehavior"> 
      <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

Gracias de antemano por cualquier ayuda que conduce a la llamada exitosa con> 65K XML; -)

Respuesta

12

Bien, este realmente me causó problemas resolviéndolo, por lo que ahorraré a otros. El desafío estaba en el hecho de que utilicé el <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="fullyQualifiedClassName" %>, que es un enfoque de implementación de fábrica agradable y fácil.

Sin embargo, este enfoque tiene sus desventajas; ya que no se necesita ninguna configuración en el archivo web.config, la clase WebServiceHostFactory por diseño nunca se lee desde el archivo web.config. Lo sé; Podría heredar de esta clase y hacer los cambios apropiados para que realmente pueda leer desde el archivo de configuración, pero esto parecía un poco fuera de alcance.

Mi solución fue volver a la forma más tradicional de implementar WCF; <%@ ServiceHost Service="fullyQualifiedClassName" CodeBehind="~/App_Code/Catalogue.cs" %>, y luego use mis valores ya configurados en el archivo web.config.

Aquí está mi archivo web.config modificada (con respecto a Maddox dolor de cabeza):

<system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="XmlMessageBinding" maxReceivedMessageSize="5000000" maxBufferPoolSize="5000000" maxBufferSize="5000000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00"> 
      <readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" /> 
      <security mode="None"/> 
     </binding> 
     </webHttpBinding> 
    </bindings> 
    <services> 
     <service name="fullyQualifiedClassName" behaviorConfiguration="DevelopmentBehavior"> 
     <endpoint name="REST" address="" binding="webHttpBinding" contract="fullyQualifiedInterfaceName" behaviorConfiguration="RestEndpointBehavior" bindingConfiguration="XmlMessageBinding" /> 
     </service> 
    </services> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="RestEndpointBehavior"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior name="DevelopmentBehavior"> 
      <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     <behavior name="ProductionBehavior"> 
      <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="false"/> 
      <serviceMetadata httpGetEnabled="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

Otro de los beneficios de este cambio es que ahora se puede hacer referencia a su servicio de WCF resto directamente de .NET; esto no se puede hacer utilizando el modelo de fábrica y mi implementación de XmlElement a través de la solución.

Espero que esto pueda ayudar a otros con problemas similares ...

+0

Estaba teniendo el mismo problema y pensé que podría ser la fábrica, gracias por confirmar esto para mí. – Alex

+0

Votación a favor porque este comportamiento es realmente poco claro y la conclusión de que ServiceRoutes no utiliza enlaces de Web.Config no parece estar documentada en ninguna parte, pero definitivamente parece ser el caso. –

0

esta es una entrada de blog que escribí que reproduce este problema con un servidor y el cliente absolutamente mínimo pieza WCF:

WCF - Fixing client side string length exceptions

En particular, es posible que necesite una Configuración de enlace personalizada. Al menos reproducir esta muestra puede darte algunas ideas para tu situación particular.

+0

Hola Michael, Gracias por su contribución. Aunque su artículo es interesante, mi desafío hasta ahora es conseguir que funcione con Fiddler. Supongo que no existe fiddler.config, por lo que no tengo configuraciones de cliente para establecer, lo que no debería importar, como estoy seguro, que Fiddler no tiene una limitación. ¿Me equivoco aquí? –

+0

¿Funciona bien usando una línea de comando u otro programa cliente .NET? No tengo idea de cómo ajustar Fiddler, pero si has verificado que tu lado del servidor puede manejar> 65k, el problema definitivamente está en el lado de Fiddler. –

+0

El desafío es que esta es una implementación de WCF liviana y realista que utiliza la clase WebServiceHostFactory. Por lo que yo entiendo, esto significa que no puedo "Agregar una referencia de servicio" porque requiere el formato WSDL (por qué no continué con su excelente enlace). –

6

Sé que esto es una pregunta muy antigua y ya tiene una respuesta ...

fin ...

Lo que hice para solucionar este "problema" creé una fábrica heredada de WebServiceHostFactory y creé un anfitrión servicio personalizado heredado de WebServiceHost

Y en el huésped que anuló el método OnOpening como esto

protected override void OnOpening() 
     { 
      base.OnOpening(); 

      foreach (var endpoint in Description.Endpoints) 
      { 
       var binding = endpoint.Binding as System.ServiceModel.Channels.CustomBinding; 

       foreach (var element in binding.Elements) 
       { 
        var httpElement = element as System.ServiceModel.Channels.HttpTransportBindingElement; 
        if (httpElement != null) 
        { 
         httpElement.MaxBufferSize = 2147483647; 
         httpElement.MaxReceivedMessageSize = 2147483647; 
        } 
       } 
      } 

     } 
+0

Esto fue muy útil. Lo usé en un entorno de SharePoint donde no pude controlar el web.config para el servicio. – MgSam

+1

¡Esto es genial! Nota: no use CreateBindings() para obtener el enlace, no funcionará. Usa el yeso como se menciona arriba. También tenga en cuenta el uso de las fábricas particulares. – CCondron

+0

¡¡¡Impresionante !!! ¡Gracias! – zdrsh

6

creo que tenía el mismo problema, pero cuando he configurado por defecto vinculante para webHttp entonces trabajado:

<bindings> 
     <webHttpBinding> 
      <binding maxReceivedMessageSize="2000000" 
         maxBufferSize="2000000"> 
       <readerQuotas maxStringContentLength="2000000"/> 
      </binding> 
     </webHttpBinding> 
    </bindings> 

Observe: no nombre en el enlace.

+1

Esto funciona perfecto si está utilizando System.ServiceModel.Activation.WebServiceHostFactory. – ROFLwTIME

Cuestiones relacionadas