2012-05-03 17 views
5

Desde mi entender lo que sigue debe lanzar correctamente un error personalizado de un servicio WCF Resto:WCF Resto manejo de errores de servicio y WebChannelFactory

[DataContract(Namespace = "")] 
public class ErrorHandler 
{ 
    [DataMember] 
    public int errorCode { get; set; } 

    [DataMember] 
    public string errorMessage { get; set; } 
} // End of ErrorHandler 

public class Implementation : ISomeInterface 
{ 
    public string SomeMethod() 
    { 
     throw new WebFaultException<ErrorHandler>(new ErrorHandler() 
     { 
      errorCode = 5, 
      errorMessage = "Something failed" 
     }, System.Net.HttpStatusCode.BadRequest); 
    } 
} 

En Fiddler Esto parece funcionar, consigo los siguientes datos en bruto:

HTTP/1.1 400 Bad Request 
Cache-Control: private 
Content-Length: 145 
Content-Type: application/xml; charset=utf-8 
Server: Microsoft-IIS/7.5 
X-AspNet-Version: 4.0.30319 
Set-Cookie: ASP.NET_SessionId=gwsy212sbjfxdfzslgyrmli1; path=/; HttpOnly 
X-Powered-By: ASP.NET 
Date: Thu, 03 May 2012 17:49:14 GMT 

<ErrorHandler xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><errorCode>5</errorCode><errorMessage>Something failed</errorMessage></ErrorHandler> 

Pero ahora en mi lado del cliente tengo el siguiente código:

WebChannelFactory<ISomeInterface> client = new WebChannelFactory<ISomeInterface>(new Uri(targetHost)); 

ISomeInterface someInterface = client.CreateChannel(); 
try 
{ 
    var result = someInterface.SomeMethod(); 
} 
catch(Exception ex) 
{ 
    // Try to examine the ErrorHandler to get additional details. 
} 

ahora, cuando el código ejecuta, golpea la captura y es un System.ServiceModel.ProtocolException con el mensaje 'El servidor remoto devolvió una respuesta inesperada: (400) Solicitud incorrecta.'. Parece que no tengo forma de ver los detalles de ErrorHandler en este punto. ¿Alguien ha topado con esto? ¿Hay alguna manera de obtener los detalles de ErrorHander en este punto?

Respuesta

4

WebChannelFactory o ChannelFactory solo le revelarán el genérico CommunicationException. Tendrá que utilizar un comportamiento IClientMessageInspector o confiar en WebRequest para devolver el error real.

Para el enfoque IClientMessageInspector - vea los comentarios en this blog entry.

Para el enfoque WebRequest, puede hacer lo siguiente para capturar el WebException.

try { } 
catch (Exception ex) 
{ 
    if (ex.GetType().IsAssignableFrom(typeof(WebException))) 
    { 
     WebException webEx = ex as WebException; 
     if (webEx.Status == WebExceptionStatus.ProtocolError) 
     { 
      using (StreamReader exResponseReader = new StreamReader(webEx.Response.GetResponseStream())) 
      { 
       string exceptionMessage = exResponseReader.ReadToEnd(); 
       Trace.TraceInformation("Internal Error: {0}", exceptionMessage); 
      } 
     } 
    } 
}