Чтение пользовательского HttpWebResponse StatusDescription? - PullRequest
3 голосов
/ 20 апреля 2009

Я устанавливаю настраиваемую StatusDescription в службе RESTful WCF при возникновении исключения. Он предназначен для того, чтобы предоставить вызывающему абоненту понятное описание того, почему он получил код состояния ошибки.

Ниже приводится ответ, который я вижу в Fiddler. Итак, я знаю, что мое пользовательское сообщение передается вызывающей стороне. Чего я не могу понять, так это как извлечь это сообщение из .NET. Описание StatusDescription не содержит эту строку.

Если бы вы могли предоставить простой пример кода, это было бы здорово.

HTTP / 1.1 500 Сообщение: «Возникло исключение типа« Exceptions.DataSourceNotFoundException ».» Uri: http://www.test1.com/
Длина контента: 0
Сервер: Microsoft-HTTPAPI / 2.0
Дата: пн, 20 апреля 2009 07:13:40 GMT

UPDATE
Ответ на этот вопрос не работает в Silverlight. Протестировано в Silverlight 2 и 3 бета.

Ответы [ 4 ]

3 голосов
/ 29 апреля 2009

Я не пользовался .NET много лет, но в Java люди часто ожидают получить HTTP-код и сообщение об ошибках 404 Not Found, в то время как 404-е фактически заставляют Java генерировать исключение FileNotFoundException. Для таких ситуаций в Java следует использовать HttpURLConnection#getErrorStream вместо #getResponseMessage.

Итак: может быть, нечто подобное происходит в клиенте .NET для 500 ответов? Действительно, документация для HttpWebRequest гласит:

Класс HttpWebRequest выдает WebException при возникновении ошибок при доступе к ресурсу. Свойство WebException.Status содержит значение WebExceptionStatus , указывающее источник ошибки. Когда WebException.Status равен WebExceptionStatus.ProtocolError , свойство Response содержит HttpWebResponse , полученный от ресурса.

Подробно: ссылка на Response выше относится к WebException.Response, а не к HttpWebRequest.GetResponse. Итак, WebException имеет собственное свойство Response. Следующий пример основан на документации WebException.Response, но я не тестировал ее.

ВАЖНО: обратите внимание, что здесь НЕ используются GetResponse с HttpWebRequest, но Response с 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);
}
3 голосов
/ 29 апреля 2009

Не программист .NET, нашел это на MSDN

catch(WebException ex)
{
    string message = ((HttpWebResponse)ex.Response).StatusDescription;
}
0 голосов
/ 02 мая 2009

Я не могу сказать, является ли это копией / вставкой, но заголовок "Uri:" находится в той же строке, что и код состояния - это может быть проблемой.

Большинство кодов причин - это несколько слов без «:» и без кавычек: http://tools.ietf.org/html/rfc2616#section-6.1.1 Поэтому я подозреваю, что анализатор заголовков считает, что «Сообщение:» является началом заголовка HTTP (проверьте webResponse.Headers [ "Message"]).

Вместо этого вы можете добавить заголовок (скажем, X-Error-Details).

0 голосов
/ 30 апреля 2009

Я думаю, что ваша проблема в том, что ваш код состояния равен 500. Когда код состояния не в порядке (200 или какой-либо тип перенаправления), вызов WebRequest.GetResponse () вызывает исключение WebException в .NET.

Это исключение будет фактически содержать объект HttpWebResponse с установленным StatusDescription. Образцы ниже взяты из 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);
        }
    }

Источник: http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.statuscode.aspx

Чтобы получить статус, вам нужно получить объект HttpWebResponse из самого исключения:

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);
}

Источник: http://msdn.microsoft.com/en-us/library/system.net.webexception.status.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...