Usage of EnsureSuccessStatusCode and handling of H

2019-01-13 11:42发布

What's the usage pattern of HttpResponseMessage.EnsureSuccessStatusCode()? It disposes of the Content of the message and throws HttpRequestException, but I fail to see how to programmatically handle it any differently than a generic Exception. For example, it doesn't include the HttpStatusCode, which would have been handy.

Is there any way of getting more info out of it? Could anyone show relevant usage pattern of both EnsureSuccessStatusCode() and HttpRequestException?

2条回答
贼婆χ
2楼-- · 2019-01-13 12:27

The idiomatic usage of EnsureSuccessStatusCode is to concisely verify success of a request, when you don't want to handle failure cases in any specific way. This is especially useful when you want to quickly prototype a client.

When you decide you want to handle failure cases in a specific way, do not do the following.

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

This throws an exception just to immediately catch it, which doesn't make any sense. The IsSuccessStatusCode property of HttpResponseMessage is there for this purpose. Do the following instead.

var response = await client.GetAsync(...);
if (response.IsSuccessStatusCode)
{
    // Handle success
}
else
{
    // Handle failure
}
查看更多
别忘想泡老子
3楼-- · 2019-01-13 12:34

I don't like EnsureSuccessStatusCode as it doesn't return anything meaninful. That is why I've created my own extension:

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

source code for Microsoft's EnsureSuccessStatusCode can be found here

Synchronous version based on SO link :

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

What I don't like about IsSuccessStatusCode is that it is not "nicely" reusable. For example you can use library like polly to repeat a request in case of network issue. In that case you need your code to raise exception so that polly or some other library can handle it...

查看更多
登录 后发表回答