2012-05-03 8 views
5

Dalla mia comprensione il seguente dovrebbe lanciare correttamente un errore personalizzato da un servizio WCF Riposo:WCF Resto gestione degli errori di servizio e 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); 
    } 
} 

In Fiddler questo sembra funzionare, ricevo il seguente dati grezzi:

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> 

Ma d'ora in poi il mio lato client ho il seguente codice:

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. 
} 

ora, quando il codice esegue, colpisce il fermo ed è un System.ServiceModel.ProtocolException con il messaggio 'Il server remoto ha restituito una risposta imprevista: (400) Richiesta non valida.'. Sembra che non abbia modo di vedere i dettagli di ErrorHandler a questo punto. qualcuno si è mai imbattuto in questo? C'è un modo per ottenere i dettagli di ErrorHander a questo punto?

risposta

4

WebChannelFactory o ChannelFactory comunicherà solo il generico CommunicationException. È necessario utilizzare un comportamento IClientMessageInspector o fare affidamento su WebRequest per restituire l'errore effettivo.

Per l'approccio IClientMessageInspector - vedere i commenti in this blog entry.

Per l'approccio WebRequest, è possibile quanto segue per prendere il 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); 
      } 
     } 
    } 
}