检查HttpStatusCode是代表成功还是失败


93

假设我有以下变量:

System.Net.HttpStatusCode status = System.Net.HttpStatusCode.OK;

如何检查这是成功状态代码还是失败状态代码?

例如,我可以执行以下操作:

int code = (int)status;
if(code >= 200 && code < 300) {
    //Success
}

我也可以有一些白名单:

HttpStatusCode[] successStatus = new HttpStatusCode[] {
     HttpStatusCode.OK,
     HttpStatusCode.Created,
     HttpStatusCode.Accepted,
     HttpStatusCode.NonAuthoritativeInformation,
     HttpStatusCode.NoContent,
     HttpStatusCode.ResetContent,
     HttpStatusCode.PartialContent
};
if(successStatus.Contains(status)) //LINQ
{
    //Success
}

这些替代方法都不能说服我,我希望可以使用.NET类或方法为我完成这项工作,例如:

bool isSuccess = HttpUtilities.IsSuccess(status);

你需要做的int code = (int)Response.StatusCode,从那里,你将需要创建自己Enum这里检查工作示例stackoverflow.com/questions/1330856/...
MethodMan

您是否有机会HttpClient上课?
dcastro

1
@dcastro不,对不起。我正在使用可以(也可以不)在内部使用的高级 API。该API响应的状态代码,但不暴露内部HttpResponseMessage例如
马蒂亚斯西塞罗

@MatiCicero太糟糕了:/您总是可以重复使用HttpResponseMessage.IsSuccessStatusCode与您的第一种方法完全相同的实现(请参阅我的答案),并将其作为HttpStatusCode类型的扩展方法。
dcastro

Answers:


173

如果您正在使用该HttpClient课程,那么您将获得一个HttpResponseMessage回报。

此类具有一个有用的属性IsSuccessStatusCode,该属性将为您进行检查。

using (var client = new HttpClient())
{
    var response = await client.PostAsync(uri, content);
    if (response.IsSuccessStatusCode)
    {
        //...
    }
}

如果您感到好奇,可以将此属性实现为:

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

因此,如果您不愿意,就可以重用此算法使用,HttpClient直接。

如果EnsureSuccessStatusCode响应不成功,您还可以使用引发异常。


仅供参考:对我来说是“响应。成功”。
Topher Birth

您的答案很有帮助,但现在它的工作方式是:if(response.IsCompletedSuccessfully){//}
salman

12

HttpResponseMessage类具有IsSuccessStatusCode属性,可以像这样查看源代码,因为usr已经建议200-299可能是您可以做的最好的事情。

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

11

可接受的答案令我有些困扰,因为它的第二部分包含魔术数字(尽管它们是标准的)。尽管很接近我的答案,但第一部分不是通用整数状态代码的通用部分。

通过使用状态代码实例化HttpResponseMessage并检查是否成功,可以实现完全相同的结果。如果值小于零或大于999,则确实会引发参数异常。

if (new HttpResponseMessage((HttpStatusCode)statusCode).IsSuccessStatusCode)
{
    // ...
}

这并不十分简洁,但是您可以对其进行扩展。


这对我来说非常理想,因为我只有HttpStatusCode而不是Response消息。做得好!
Todd Vance

5
“被接受的答案令我有些困扰,因为它包含幻数(尽管它们是标准的)”-如果它们标准化,易于理解且永不改变,它们就不是“幻数”。直接使用代码绝对没有错。如果您有IsSuccessStatusCode出色的表现,请使用它(如公认的答案所述。)否则,请勿使用抽象添加您自己的面包屑,除非您在各处进行此项检查
Ed S.

1
请记住,实例化HttpResponseMessage使用其属性之一比使用来检查两个逻辑条件要花费更多的时间int
Miro J.

10

添加到@TomDoesCode答案如果您使用的是HttpWebResponse,则可以添加以下扩展方法:

public static bool IsSuccessStatusCode(this HttpWebResponse httpWebResponse)
{
    return ((int)httpWebResponse.StatusCode >= 200) && ((int)httpWebResponse.StatusCode <= 299);
}

8

我偏爱扩展方法的发现。

public static class HttpStatusCodeExtensions
{
    public static bool IsSuccessStatusCode(this HttpStatusCode statusCode)
    {
        var asInt = (int)statusCode;
        return asInt >= 200 && asInt <= 299;
    }
}

只要您的名称空间在范围内,用法就为statusCode.IsSuccessStatusCode()


2
您可能想要asInt> = 200
Jim O'Neil

扩展方法很酷,但是我很困惑-这与HTTPClient或IHTTPClientFactory所使用的HTTPResponseMessage的IsSuccessStatusCode属性是否具有相同的功能?@DCastro甚至向我们展示了它在.NET中的实现完全相同。何时/为什么要对2xx范围内的HTTP状态代码使用这样的扩展方法?
sfors说要恢复莫妮卡

4
@sfors,是的,但是如果您只有HttpStatusCode范围,该怎么办?有很多不使用或HttpResponseMessage不公开但可以为您提供状态代码的库。
bojingo

3

这取决于您要调用的HTTP资源。通常,2xx范围定义为成功状态代码的范围。显然,这并不是每个HTTP服务器都遵守的约定。

例如,在网站上提交表单通常会返回302重定向。

如果您想设计一个通用方法,那么这个code >= 200 && code < 300想法可能是您最好的选择。

如果要调用自己的服务器,则可能应确保对进行标准化200


2

这是上一个答案的扩展,它避免了每次调用都会为新对象创建和随后的垃圾回收。

public static class StatusCodeExtensions
{
    private static readonly ConcurrentDictionary<HttpStatusCode, bool> IsSuccessStatusCode = new ConcurrentDictionary<HttpStatusCode, bool>();
    public static bool IsSuccess(this HttpStatusCode statusCode) => IsSuccessStatusCode.GetOrAdd(statusCode, c => new HttpResponseMessage(c).IsSuccessStatusCode);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.