System.Net.WebException HTTP状态代码


Answers:


248

也许是这样的...

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

8
@rusty:你不能。如果连接失败,则没有HTTP状态代码。
2014年

4
如果错误是ProtocolError,则不必检查响应是否为null。请参阅此MSDN页面
Andras Toth,2014年

5
@AndrasToth但是,如果省略了空检查,诸如ReSharper之类的工具将向您发出警告。在任何情况下,防御性编码都是一个好习惯。
汤姆·林特

1
如何获得HTTP Substatus值?例如,404.13内容长度太大参考docs.microsoft.com/en-us/iis/configuration/system.webServer/…–
Kiquenet,

27

通过使用空条件运算符?.),您可以使用单行代码获取HTTP状态代码:

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

该变量status将包含HttpStatusCode。当出现更常见的故障(例如网络错误)时,如果从未发送过HTTP状态代码,则status它将为null。在这种情况下,您可以检查ex.Status以获取WebExceptionStatus

如果您只想在发生故障时记录描述性字符串,则可以使用null运算符??)来获取相关的错误:

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

如果由于404 HTTP状态代码而引发异常,则该字符串将包含“ NotFound”。另一方面,如果服务器处于脱机状态,则该字符串将包含“ ConnectFailure”,依此类推。

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


不确定?.在预览发布期间该运算符最初是被命名为null传播运算符还是null条件运算符。但是Atlassian reshaper会警告在这种情况下使用空传播算子。很高兴知道它也称为空条件运算符。
RBT

1
这次聚会晚了一点,但是警告说空条件运算符是C#6.0功能,因此需要使用支持它的编译器。堆栈溢出答案以及更多详细信息。VS 2015+默认情况下具有此功能,但如果使用的不是“其机器”,而是使用任何类型的构建/部署环境,则可能需要考虑其他因素。
CodeHxr

9

仅在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

4
@ympostor这只是一个例子。任何合理的开发人员都可以理解这一点。您的评论是我在这里读过的最粗心的评论。
pr0gg3r

9

(我确实知道这个问题很老,但这是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

您可以尝试使用此代码从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;
}

1
return 0?或更好HttpStatusCode?可为null)?
Kiquenet '18

这样行吗?var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF '18

我无法理解您在此示例中想要做什么。在什么情况下您想要记录事件?
谢尔盖(Sergey)

1

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

您能否向我们提供更多有关您要使用该代码完成的信息。可能会有更好的方法来获取您所需的信息。

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.