Код статусу HTTP System.Net.WebException


Відповіді:


248

Можливо, щось подібне ...

try
{
    // ...
}
catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        }
        else
        {
            // no http status code available
        }
    }
    else
    {
        // no http status code available
    }
}

але у випадку винятку "connectfailure", ми отримуємо відповідь як недійсна, у такому випадку як я можу отримати код httpstatus
Rusty

8
@rusty: Не можна. Якщо відбувається збою підключення, то код статусу HTTP неможливо отримати.
ЛукаХ

4
Якщо помилкою є ProtocolError, вам не доведеться перевіряти відповідь на null. Дивіться коментар у прикладі на цій сторінці MSDN
Андрас Тот

5
@AndrasToth Але такі інструменти, як ReSharper, надішлять вам попередження, якщо пропустити нульову перевірку. І в будь-якому випадку, це хороша практика кодувати оборонно.
Том Лінт,

1
Як отримати значення HTTP Substatus ? Наприклад, 404.13 Довжина вмісту Занадто велика довідка : docs.microsoft.com/en-us/iis/configuration/system.webServer/…
Кікенет

27

Використовуючи нульовий умовний оператор ( ?.), ви можете отримати код статусу HTTP за допомогою одного рядка коду:

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

Змінна statusбуде містити HttpStatusCode. Коли є більш загальний збій, як помилка мережі, коли жодного коду статусу HTTP ніколи не надсилається, то statusце буде нульовим. У такому випадку ви можете перевірити, ex.Statusщоб отримати WebExceptionStatus.

Якщо ви просто хочете, щоб описовий рядок входив у журнал у разі відмови, ви можете скористатися оператором зв'язання з нулем ( ??), щоб отримати відповідну помилку:

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

Якщо виняток буде викинуто в результаті коду статусу HTTP 404, рядок буде містити "NotFound". З іншого боку, якщо сервер перебуває в офлайні, рядок буде містити "ConnectFailure" тощо.

(І для всіх, хто хоче знати, як отримати код субстатута HTTP. Це неможливо. Це концепція Microsoft IIS, яка лише реєструється на сервері і ніколи не надсилається клієнту.)


Не впевнений, що ?.оператор спочатку був названий оператором поширення нуля або оператором з нульовим умовою під час випуску попереднього перегляду. Але Atlassian resharper дає попередження використовувати оператор нульового поширення в таких сценаріях. Приємно знати, що його також називають нульовим умовним оператором.
RBT

1
Трохи запізнюється на цю сторону, але справедливе попередження про те, що умовний оператор - це функція C # 6.0, тому потрібно використовувати компілятор, який її підтримує. Відповідь на переповнення стека з додатковими подробицями . У VS 2015+ його встановлено за замовчуванням, але якщо хтось використовує будь-яке середовище побудови / розгортання, окрім лише "своєї машини", можливо, потрібно буде врахувати й інші речі.
CodeHxr

9

це працює лише в тому випадку, якщо WebResponse є HttpWebResponse.

try
{
    ...
}
catch (System.Net.WebException exc)
{
    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        MessageBox.Show("401");
    }
    else
        throw;
}

чому тільки мати справу з 401-Несанкціонованим замість усіх можливих кодів помилок HTTP? це найгірша відповідь
ympostor

4
@ympostor Це лише приклад. Будь-який розумний розробник це розуміє. Ваш коментар є найбільш бездумним, що я тут коли-небудь читав.
pr0gg3r

9

(Я розумію, що питання давнє, але воно входить до числа найкращих хітів в Google.)

Поширена ситуація, коли ви хочете знати код відповіді - це обробка виключень. Станом на C # 7, ви можете використовувати відповідність шаблонів, щоб фактично ввести пункт про вилов лише у тому випадку, якщо виняток відповідає вашому предикату:

catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
     doSomething(response.StatusCode)
}

Це легко можна поширити на подальші рівні, наприклад, у цьому випадку, коли WebExceptionнасправді був внутрішній виняток іншого (і нас цікавить лише 404):

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

Нарешті: зауважте, як немає потреби повторно кидати виняток у пункті вилову, якщо він не відповідає вашим критеріям, оскільки ми не вводимо цей пункт в першу чергу з вищевказаним рішенням.


4

Ви можете спробувати цей код, щоб отримати код статусу HTTP від ​​WebException. Він працює і в Silverlight, оскільки в SL не визначено WebExceptionStatus.ProtocolError.

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}

1
return 0? чи краще HttpStatusCode?( нульовий )?
Кікенет

Чи буде це працювати? var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF

Я не можу зрозуміти, що ти хотів зробити в цьому зразку. У яких випадках ви хотіли записати подію?
Сергій

1

Я не впевнений, чи є, але якби було таке майно, це не вважалося б надійним. А WebExceptionможе бути звільнено з причин, відмінних від кодів помилок HTTP, включаючи прості помилки в мережі. У них немає такого відповідного коду помилки http.

Чи можете ви надати нам трохи більше інформації про те, що ви намагаєтеся виконати з цим кодом. Можливо, буде кращий спосіб отримати потрібну інформацію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.