2008-11-27 30 views
12

Tengo un servicio de WCF con la siguiente configuración:error HTTP Solicitud incorrecta al solicitar un contrato de servicio WCF

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="MetadataEnabled"> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
       <serviceMetadata httpGetEnabled="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
     <services> 
      <service behaviorConfiguration="MetadataEnabled" name="MyNamespace.MyService"> 
       <endpoint name="BasicHttp" 
         address="" 
         binding="basicHttpBinding" 
         contract="MyNamespace.IMyServiceContract" /> 
       <endpoint name="MetadataHttp" 
         address="contract" 
         binding="mexHttpBinding" 
         contract="IMetadataExchange" /> 
       <host> 
        <baseAddresses> 
         <add baseAddress="http://localhost/myservice" /> 
        </baseAddresses> 
       </host> 
      </service> 
    </services> 
</system.serviceModel> 

Cuando aloja el servicio en el proceso WcfSvcHost.exe, si hojeo a la URL:

http://localhost/myservice/contract

donde el servicio está disponible metadatos me sale un HTTP 400 Error de solicitud.

Mediante la inspección de los registros de WCF descubrí que un System.Xml.XmlException excepción se está lanzando con el mensaje: "El cuerpo del mensaje no se puede leer porque está vacío"
Aquí es un extracto del archivo de registro:

<Exception> 
<ExceptionType> 
System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
</ExceptionType> 
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message> 
<StackTrace> 
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage() 
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback) 
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result) 
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result) 
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) 
at System.Net.LazyAsyncResult.Complete(IntPtr userToken) 
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) 
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) 
</StackTrace> 
<InnerException> 
<ExceptionType>System.Xml.XmlException, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> 
<Message>The body of the message cannot be read because it is empty.</Message> 
<StackTrace> 
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage() 
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback) 
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result) 
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result) 
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) 
at System.Net.LazyAsyncResult.Complete(IntPtr userToken) 
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) 
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) 
</StackTrace> 
</InnerException> 
</Exception> 

Si en lugar de examinar la URL:

http://localhost/myservice?wsdl

todo funciona bien y obtengo el contrato WSDL. En este punto, también puedo eliminar por completo el punto final de metadatos "MetadataHttp", y no haría ninguna diferencia.

Estoy usando .NET 3.5 SP1. ¿Alguien tiene una idea de lo que podría estar mal aquí?

+1

He visto este comportamiento también cuando utilicé varios puntos finales. Nunca encontré la respuesta :(. – leppie

+5

Literalmente odio WCF ... – Jammer

Respuesta

12

Creo que descubrí cuál es el problema.

Si hojeo a la URL:

http://localhost/myservice/contract

con la aplicaciónWcfTestClient puedo recuperar correctamente los metadatos del servicio.
Entonces, el error realmente solo ocurre cuando solicito la URL a través de un navegador web.

El HTTP Bad Request error proviene del hecho de que el navegador emite una solicitud HTTP GET donde el contenido del mensaje está en los encabezados HTTP, y el cuerpo está vacío.
Esto es exactamente lo que el WCF mexHttpBinding ¡se queja!

Con el fin de llegar al contrato de servicio a través de un navegador web que tendrá que activar de forma explícita en el comportamiento del servicio:

<serviceBehaviors> 
    <behavior name="MetadataEnabled"> 
     <serviceMetadata httpGetEnabled="true" /> 
    </behavior> 
</serviceBehaviors> 

La URL a la solicitud se hace a continuación:

http://localhost/myservice?wsdl

Entonces, resultó ser demasiado rápido para publicar esta pregunta.Sin embargo, lo mantendré de todos modos solo para el registro.

+0

Tuve el mismo problema, resulta que no agregué el extremo de un servicio en mi prod web.config –

3

Pude solucionar el problema de "400 solicitudes incorrectas" al cambiar mi servicio WCF de Visual Studio Development Server a servidor web IIS local (haga clic con el botón derecho en el proyecto -> propiedades -> pestaña web -> botón de opción en "Servidores"). Espero que esto ayude a alguien porque me tomó dos días resolver esto.

4

Generalmente, este es un problema con el tamaño del sobre de SOAP. Compruebe su configuración de enlace para cambiar MaxBufferPoolSize, MaxReceivedMessageSize para permitir grandes contenidos. Recuerde, debe cambiar tanto en el lado del cliente como del servidor.

Otro problema es el MessageEnconding (otro parámetro de enlace), asegúrese de que el lado del cliente y del servidor estén usando la misma codificación.

Finalmente, verifique los parámetros de las propiedades de las cuotas del lector.

1

Si no está seguro de por qué su código WCF arroja un error, le recomiendo el MS Service Trace Viewer. Es muy útil para identificar problemas de comunicación y transporte como este. Eche un vistazo a este artículo C# Corner para más detalles.

2

Tuve HTTP 400 problemas al consumir una URL HTTPS mex de SvcUtil, aunque httpsGetEnabled se configuró en true. El mensaje de error estaba muy lejos de lo que realmente era el problema, así que estoy publicando aquí en caso de que alguien se tropiece con el mismo problema.

Tenía un certificado de CA autofirmado (TestRootCA) que era el emisor del certificado del servidor (localhost). En el cliente, importé el archivo TestRootCA CER pero no importé la CRL (lista de revocación de certificados). Parece que cuando utiliza una CA autofirmada, debe también importar la CRL; de lo contrario, la autenticación del servidor falla de manera extraña, ninguna de las cuales lo señala al problema real. Lo que es peor es que el error ocurre durante el protocolo de enlace SSL, antes de, la solicitud llega incluso a su servicio, por lo que no verá errores en los registros de seguimiento WCF.

Cuestiones relacionadas