EnsureSuccessStatusCode的使用和处理抛出的HttpRequestException

什么是HttpResponseMessage.EnsureSuccessStatusCode()的使用模式? 它处理消息的内容并抛出HttpRequestException ,但是我看不到如何以一种通用的Exception来编程处理它。 例如,它不包括HttpStatusCode ,这本来是非常方便的。

有没有办法从中获得更多信息? 任何人都可以显示EnsureSuccessStatusCode()和HttpRequestException的相关使用模式?

EnsureSuccessStatusCode的习惯用法是,当您不想以任何特定的方式处理失败案例时,简要地validation请求的成功。 当你想快速build立一个客户端的原型时,这是特别有用的。

当您决定要以特定方式处理失败案例时, 请勿执行以下操作。

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

这只是抛出一个exception立即捕捉它,这是没有任何意义的。 HttpResponseMessageIsSuccessStatusCode属性就是为了这个目的。 做相反的事情。

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

我不喜欢EnsureSuccessStatusCode,因为它不会返回任何意思。 这就是为什么我创build了自己的扩展:

 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的源代码可以在这里find

基于SO链路的同步版本:

 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是它不是很好的可重复使用。 例如,您可以使用像polly这样的库在networking问题的情况下重复请求。 在这种情况下,您需要您的代码来引发exception,以便polly或其他库可以处理它…

我知道这不是最好的办法,但我使用这样的:

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

请让我知道,如果你有任何最好的解决scheme。

最好的问候,北京