2009-04-20 5 views
3

Je définis une StatusDescription personnalisée dans un service WCF RESTful lorsqu'une exception est levée. Il est destiné à fournir à l'appelant une description amicale de la raison pour laquelle il a reçu le code d'état d'échec.Lecture personnalisée HttpWebResponse StatusDescription?

Voici la réponse que je vois dans Fiddler. Je sais donc que mon message personnalisé est renvoyé à l'appelant. Ce que je ne peux pas comprendre, c'est comment récupérer ce message à partir de .NET. La StatusDescription ne contient pas cette chaîne.

Si vous pouviez fournir un simple échantillon de code, ce serait génial.

HTTP/1.1 500 Message: "Exception de type 'Exceptions.DataSourceNotFoundException' a été levée." Uri: http://www.test1.com/
Content-Length: 0
serveur: Microsoft-HTTPAPI/2.0
Date: 20 avril 2009 07:13:40 GMT

MISE À JOUR
La réponse à cette question ne fonctionne pas dans Silverlight. Testé dans Silverlight 2 et 3 beta.

Répondre

2

Pas un programmeur .NET, trouvé sur msdn

catch(WebException ex) 
{ 
    string message = ((HttpWebResponse)ex.Response).StatusDescription; 
} 
+3

@ spoon16, prenez soin d'expliquer pourquoi vous avez changé cette mauvaise réponse, puis accepté comme la meilleure réponse? – Arjan

3

Je n'ai pas utilisé .NET depuis plusieurs années, mais les gens attendent souvent Java pour obtenir un code HTTP et le message pour 404 erreurs non trouvé , alors que 404 fait que Java lance une exception FileNotFoundException. Pour ces situations, Java devrait utiliser HttpURLConnection#getErrorStream plutôt que #getResponseMessage. Donc: peut-être que quelque chose de similaire se passe dans un client .NET pour 500 réponses? En effet, le documentation for HttpWebRequest déclare:

La classe HttpWebRequest jette un WebException lorsque des erreurs se produisent lors de l'accès à une ressource. La propriété WebException.Status contient une valeur WebExceptionStatus qui indique la source de l'erreur. Lorsque WebException.Status est WebExceptionStatus.ProtocolError, la propriété Response contient le HttpWebResponse reçu de la ressource.

Détail: le lien vers Response fait référence ci-dessus pour WebException.Response, pas HttpWebRequest.GetResponse. Ainsi, WebException a sa propre propriété Response. L'exemple suivant est basé sur la documentation WebException.Response, mais je ne l'ai pas testé.

IMPORTANT: Veuillez noter que cela ne PAS utiliser GetResponse de HttpWebRequest, mais Response de WebException:

try { 
    HttpWebRequest myHttpWebRequest = 
     (HttpWebRequest) WebRequest.Create("http://www.example.org/not_found"); 
    HttpWebResponse myHttpWebResponse = 
     (HttpWebResponse) myHttpWebRequest.GetResponse(); 
    myHttpWebResponse.Close(); 
} 
catch(WebException e) { 
    Console.WriteLine("Exception Message: " + e.Message); 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
    Console.WriteLine("Status Code: {0}", 
     ((HttpWebResponse)e.Response).StatusCode); 
    Console.WriteLine("Status Description: {0}", 
     ((HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
catch(Exception e) { 
    Console.WriteLine(e.Message); 
} 
0

Je pense que votre problème est que votre code d'état est 500. Lorsque le code d'état est pas OK (200 ou un certain type de redirection), l'appel WebRequest.GetResponse() lève une exception WebException dans .NET.

Cette exception contiendra en réalité l'objet HttpWebResponse avec l'ensemble StatusDescription.Les exemples ci-dessous sont de MSDN:

public static void GetPage(String url) 
    { 
     try 
      {  
       // Creates an HttpWebRequest for the specified URL. 
       HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); 
       // Sends the HttpWebRequest and waits for a response. 
       HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 
       if (myHttpWebResponse.StatusCode == HttpStatusCode.OK) 
        Console.WriteLine("\r\nResponse Status Code is OK and StatusDescription is: {0}", 
             myHttpWebResponse.StatusDescription); 
       // Releases the resources of the response. 
       myHttpWebResponse.Close(); 

      } 
     catch(WebException e) 
      { 
       Console.WriteLine("\r\nWebException Raised. The following error occured : {0}",e.Status); 
      } 
     catch(Exception e) 
     { 
      Console.WriteLine("\nThe following Exception was raised : {0}",e.Message); 
     } 
    } 

Source: http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.statuscode.aspx

Pour obtenir réellement à l'état, vous aurez besoin d'obtenir l'objet HttpWebResponse de l'exception elle-même:

try { 
    // Create a web request for an invalid site. Substitute the "invalid site" strong in the Create call with a invalid name. 
    HttpWebRequest myHttpWebRequest = (HttpWebRequest) WebRequest.Create("invalid site"); 

    // Get the associated response for the above request. 
    HttpWebResponse myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse(); 
    myHttpWebResponse.Close(); 
} 
catch(WebException e) { 
    Console.WriteLine("This program is expected to throw WebException on successful run."+ 
         "\n\nException Message :" + e.Message); 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
     Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode); 
     Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
catch(Exception e) { 
    Console.WriteLine(e.Message); 
} 

Source : http://msdn.microsoft.com/en-us/library/system.net.webexception.status.aspx

+0

Errrr, comment est-ce différent des réponses précédentes? – Arjan

0

Je ne peux pas dire si c'est un copier/coller, mais l'en-tête "Uri:" est sur la même ligne que le code d'état - qui pourrait être un poursuivre en justice.

La plupart des codes raison sont quelques mots sans ":" et sans guillemets: http://tools.ietf.org/html/rfc2616#section-6.1.1 Donc je soupçonne que l'analyseur d'en-tête pense que "Message:" est le début d'un en-tête HTTP (vérifier webResponse.Headers ["Message" ]).

Vous pouvez ajouter un en-tête (par exemple, X-Error-Details) à la place.

Questions connexes