System.Net.WebException HTTP 状态码

Posted

技术标签:

【中文标题】System.Net.WebException HTTP 状态码【英文标题】:System.Net.WebException HTTP status code 【发布时间】:2011-04-06 13:19:41 【问题描述】:

有没有一种简单的方法可以从 System.Net.WebException 获取 HTTP 状态代码?

【问题讨论】:

【参考方案1】:

也许是这样的......

try

    // ...

catch (WebException ex)

    if (ex.Status == WebExceptionStatus.ProtocolError)
    
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        
        else
        
            // no http status code available
        
    
    else
    
        // no http status code available
    

【讨论】:

但是在 webexception 的“connectfailure”异常的情况下,我得到的响应为 null,在这种情况下我怎样才能得到 httpstatus 代码 @rusty:你不能。如果连接失败,则不会获取 HTTP 状态代码。 如果错误是ProtocolError,您不必检查响应是否为空。请参阅此MSDN page 示例中的注释 @AndrasToth 但是,如果您省略空检查,ReSharper 等工具会给您一个警告。在任何情况下,防御性编码都是一种很好的做法。 如何获取 HTTP Substatus 值?例如,404.13 Content Length Too Large Reference:docs.microsoft.com/en-us/iis/configuration/system.webServer/…【参考方案2】:

通过使用null-conditional operator (?.),您可以通过一行代码获取 HTTP 状态码:

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

变量status 将包含HttpStatusCode。当出现更一般的故障时,比如网络错误,没有发送 HTTP 状态代码,那么status 将为空。在这种情况下,您可以检查ex.Status 以获取WebExceptionStatus

如果您只想在发生故障时记录一个描述性字符串,您可以使用null-coalescing operator (??) 来获取相关错误:

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

如果由于 404 HTTP 状态代码引发异常,则字符串将包含“NotFound”。另一方面,如果服务器离线,则字符串将包含“ConnectFailure”等。

(对于任何想知道如何获取 HTTP 子状态的人 代码。这是不可能的。它是一个 Microsoft IIS 概念,仅 登录服务器,从未发送到客户端。)

【讨论】:

不确定?. 运算符在预览版期间最初是否命名为空传播运算符或空条件运算符。但是 Atlassian resharper 警告在这种情况下使用空传播运算符。很高兴知道它也被称为空条件运算符。 这个聚会有点晚了,但公平地警告说,空条件运算符是 C# 6.0 的一项功能,因此需要使用支持它的编译器。 Stack Overflow answer with further details。 VS 2015+ 默认有它,但如果使用任何类型的构建/部署环境而不只是“他们的机器”,则可能需要考虑其他因素。【参考方案3】:

(我确实意识到这个问题很老了,但它是 Google 上的热门问题之一。)

您想知道响应代码的常见情况是异常处理。从 C# 7 开始,您可以使用模式匹配实际上仅在异常与您的谓词匹配时才输入 catch 子句:

catch (WebException ex) when (ex.Response is HttpWebResponse response)

     doSomething(response.StatusCode)

这可以很容易地扩展到更高的级别,例如在这种情况下,WebException 实际上是另一个内部异常(我们只对 404 感兴趣):

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

最后:请注意,当 catch 子句不符合您的条件时,无需重新抛出异常,因为我们没有在上述解决方案中首先输入该子句。

【讨论】:

【参考方案4】:

仅当 WebResponse 是 HttpWebResponse 时才有效。

try

    ...

catch (System.Net.WebException exc)

    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    
        MessageBox.Show("401");
    
    else
        throw;

【讨论】:

为什么只处理 401-Unauthorized 而不是所有可能的 HTTP 错误状态码?这是最糟糕的答案 @ympostor 这只是一个例子。任何理性的开发者都明白这一点。你的评论是我在这里读到的最无脑的评论。【参考方案5】:

您可以尝试使用此代码从 WebException 获取 HTTP 状态代码。它也适用于 Silverlight,因为 SL 没有定义 WebExceptionStatus.ProtocolError。

HttpStatusCode GetHttpStatusCode(WebException we)

    if (we.Response is HttpWebResponse)
    
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    
    return null;

【讨论】:

return 0 ?还是更好的 HttpStatusCode? (可为空)? 这行得通吗? var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1); 我不明白你想在这个示例中做什么。您希望在什么情况下记录事件?【参考方案6】:

我不确定是否有,但如果有这样的财产,它就不会被认为是可靠的。 WebException 可以由于 HTTP 错误代码以外的原因(包括简单的网络错误)被触发。那些没有这样匹配的http错误代码。

您能否向我们提供更多信息,说明您尝试使用该代码完成的工作。可能有更好的方法来获取您需要的信息。

【讨论】:

以上是关于System.Net.WebException HTTP 状态码的主要内容,如果未能解决你的问题,请参考以下文章

System.Net.WebException:无法解析远程名称:

System.Net.WebException:操作已超时

System.Net.WebException HTTP 状态码

System.Net.WebException:请求被中止:请求被取消

ArangoDB-NET 错误:System.Net.WebException:'不知道这样的主机 不知道这样的主机'

System.Net.WebException 的 Powershell 处理