Использование 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 }
Это бросает исключение, чтобы сразу же поймать его, что не имеет никакого смысла. Элемент
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); }
что мне не нравится в IsSuccessStatusCode, так это то, что он не "красиво" многоразовый. Например, вы можете использовать библиотеку, как Поли повторить a запрос в случае проблем с сетью. В этом случае вам нужно, чтобы ваш код вызывал исключение, чтобы Полли или какая-либо другая библиотека могли его обрабатывать...
Я знаю, что это не лучший способ сделать это, но я использую такой:
try { ... } catch (HttpRequestException exception) { if (exception.Message.Contains("401 (Unauthorized)")) { statusCode = HttpStatusCode.Unauthorized; } else if (exception.Message.Contains("403 (Forbidden)")) { statusCode = HttpStatusCode.Forbidden; } }
пожалуйста, дайте мне знать, если у вас есть лучшее решение.