Использование EnsureSuccessStatusCode и обработка HttpRequestException он бросает

каков шаблон использования HttpResponseMessage.EnsureSuccessStatusCode()? Он избавляется от содержания сообщения и выбрасывает HttpRequestException, но я не вижу, как программно обрабатывать его иначе, чем общий Exception. Например, он не включает HttpStatusCode, который было бы удобно.

есть ли способ получить больше информации из него? Может ли кто-нибудь показать соответствующий шаблон использования обоих EnsureSuccessStatusCode() и HttpRequestException?

3 ответов


идиоматическое использование EnsureSuccessStatusCode - это лаконичная проверка успеха запроса, когда вы не хотите обрабатывать случаи сбоя каким-либо конкретным образом. Это особенно полезно, когда вы хотите быстро создать прототип клиента.

когда вы решите, что вы хотите обрабатывать случаи отказа определенным образом, не выполните следующие действия.

var response = await client.GetAsync(...);
try
{
    response.EnsureSuccessStatusCode();
    // Handle success
}
catch (HttpRequestException)
{
    // Handle failure
}

это вызывает исключение, чтобы сразу поймать его, что не имеет никакого смысла. The IsSuccessStatusCode собственность HttpResponseMessage is там для этой цели. Вместо этого сделайте следующее.

var response = await client.GetAsync(...);
if (response.IsSuccessStatusCode)
{
    // Handle success
}
else
{
    // Handle failure
}

мне не нравится EnsureSuccessStatusCode, поскольку он не возвращает ничего значимого. Вот почему я создал свое собственное расширение:

public static class HttpResponseMessageExtensions
{
    public static async Task EnsureSuccessStatusCodeAsync(this HttpResponseMessage response)
    {
        if (response.IsSuccessStatusCode)
        {
            return;
        }

        var content = await response.Content.ReadAsStringAsync();

        if (response.Content != null)
            response.Content.Dispose();

        throw new SimpleHttpResponseException(response.StatusCode, content);
    }
}

public class SimpleHttpResponseException : Exception
{
    public HttpStatusCode StatusCode { get; private set; }

    public SimpleHttpResponseException(HttpStatusCode statusCode, string content) : base(content)
    {
        StatusCode = statusCode;
    }
}

исходный код для Microsoft EnsureSuccessStatusCode можно найти здесь

синхронная версия на основе ссылка :

public static void EnsureSuccessStatusCode(this HttpResponseMessage response)
{
    if (response.IsSuccessStatusCode)
    {
        return;
    }

    var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

    if (response.Content != null)
        response.Content.Dispose();

    throw new SimpleHttpResponseException(response.StatusCode, content);
}
Поли повторить a запрос в случае сетевой проблемы. В этом случае вам нужно, чтобы ваш код вызвал исключение, чтобы Полли или какая-либо другая библиотека могли его обработать...

Я знаю, что это не лучший способ сделать это, но я использую такой:

try
{
    ...
}
catch (HttpRequestException exception)
{
    if (exception.Message.Contains("401 (Unauthorized)"))
    {
        statusCode = HttpStatusCode.Unauthorized;
    }
    else if (exception.Message.Contains("403 (Forbidden)"))
    {
        statusCode = HttpStatusCode.Forbidden;
    }
}

пожалуйста дайте мне знать если вы имеете любое самое лучшее решение.