【问题标题】:Checking if HttpStatusCode represents success or failure检查 HttpStatusCode 是代表成功还是失败
【发布时间】:2015-09-14 16:48:18
【问题描述】:

假设我有以下变量:

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/…
  • 您是否有机会使用HttpClient 类?
  • @dcastro 不,对不起。我正在使用可能(或可能不会)在内部使用它的 高级 API。 API 会暴露响应的状态码,但不会暴露内部的 HttpResponseMessage 例如
  • @MatiCicero 太糟糕了:/ 您始终可以重用 HttpResponseMessage.IsSuccessStatusCode 的实现(请参阅我的回答),这与您的第一种方法完全相同,并使其成为 @987654331 上的扩展方法@类型。

标签: c# .net system.net


【解决方案1】:

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

这个类有一个有用的属性叫做IsSuccessStatusCode,它会为你做检查。

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

如果你好奇,这个属性是implemented

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

所以如果你直接使用HttpClient,你可以重用这个算法。

您也可以使用EnsureSuccessStatusCode 抛出异常,以防响应不成功。

【讨论】:

  • 仅供参考:对我来说是“response.IsSuccessful”。
  • 您的回答很有帮助,但现在它的工作方式如下: if (response.IsCompletedSuccessfully) { // }
【解决方案2】:

接受的答案让我有点困扰,因为它在第二部分包含幻数(尽管它们是标准的)。第一部分不是普通整数状态代码的通用部分,尽管它接近我的答案。

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

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

这不是很简洁,但您可以将其作为扩展。

【讨论】:

  • 这对我来说非常有效,因为我只有一个 HttpStatusCode 而不是一个响应消息。干得好!
  • “接受的答案让我有点困扰,因为它包含了神奇的数字,(尽管它们是标准的)” - 如果它们是标准化的、很好理解的并且永远不会发生,它们就不是“神奇的”改变。直接使用代码绝对没有错。如果您有 IsSuccessStatusCode 那就太好了,请使用它(正如公认的答案所说)。否则,除非您在整个地方执行此检查,否则不要使用抽象添加您自己的垃圾
  • 请记住,实例化HttpResponseMessage 以使用其属性之一比使用int 检查两个逻辑条件需要更多时间。
【解决方案3】:

HttpResponseMessage 类有一个 IsSuccessStatusCode 属性,查看源代码是这样的,因为 usr 已经建议 200-299 可能是你能做的最好的。

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

【讨论】:

    【解决方案4】:

    添加到@TomDoesCode 答案如果您使用的是 HttpWebResponse 你可以添加这个扩展方法:

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

    【讨论】:

      【解决方案5】:

      我偏爱扩展方法的可发现性。

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

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

      【讨论】:

      • 扩展方法很酷,但我很困惑 - 这与 HTTPClient 或 IHTTPClientFactory 使用的 HTTPResponseMessage 的 IsSuccessStatusCode 属性不一样吗? @DCastro 甚至向我们展示了它在 .NET 中的实现方式与此完全一样。何时/为什么要对 2xx 范围内的 HTTP 状态代码使用这样的扩展方法?
      • @sfors,是的,但是如果您的范围内只有 HttpStatusCode 怎么办?有很多库不使用或显示 HttpResponseMessage,但会为您提供状态代码。
      【解决方案6】:

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

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

      如果您想设计一种通用方法,那么code &gt;= 200 &amp;&amp; code &lt; 300 想法可能是您的最佳选择。

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          猜你喜欢
          • 2019-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-28
          • 1970-01-01
          相关资源
          最近更新 更多