Checking if HttpStatusCode represents success or failure

假设我有以下变量:

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
}

None of these alternatives convinces me, and I was hoping for a .NET class or method that can do this work for me, such as:

bool isSuccess = HttpUtilities.IsSuccess(status);
112081 次浏览

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

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

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

如果您正在调用您的 自己的服务器,那么您可能应该确保您在 200上进行了标准化。

HttpResponseMessage 类有一个 IsSuccess StatusCode 属性,查看源代码如下所示,因此 usr 已经建议200-299可能是最佳选择。

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

如果您使用的是 HttpClient类,那么您将得到一个 HttpResponseMessage

This class has a useful property called IsSuccessStatusCode that will do the check for you.

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引发异常。

Adding to @TomDoesCode answer If you are using HttpWebResponse you can add this extension method:

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

The accepted answer bothers me a bit as it contains magic numbers, (although they are in standard) in its second part. And first part is not generic to plain integer status codes, although it is close to my answer.

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

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

这并不完全简洁,但你可以把它扩展一下。

这是前一个答案的扩展,避免了为每个调用创建新对象并随后进行垃圾收集。

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

我更倾向于扩展方法的可发现性。

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

As long as your namespace is in scope, usage would be statusCode.IsSuccessStatusCode().