为啥 HttpWebRequest 会抛出异常而不是返回 HttpStatusCode.NotFound?

Posted

技术标签:

【中文标题】为啥 HttpWebRequest 会抛出异常而不是返回 HttpStatusCode.NotFound?【英文标题】:Why does HttpWebRequest throw an exception instead returning HttpStatusCode.NotFound?为什么 HttpWebRequest 会抛出异常而不是返回 HttpStatusCode.NotFound? 【发布时间】:2012-04-10 00:53:54 【问题描述】:

我正在尝试使用 HttpWebRequest 验证 Url 的存在。我发现了一些基本上可以做到这一点的例子:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
request.Method = "HEAD";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)

    return response.StatusCode;

但是,如果 url 确实损坏了,它不会返回响应,而是抛出异常。

我将我的代码修改为:

try

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
    request.Method = "HEAD";
    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    
        return response.StatusCode;
    

catch (System.Net.WebException ex)

    var response = ex.Response as HttpWebResponse;
    return response == null ? HttpStatusCode.InternalServerError : response.StatusCode;

这似乎终于做到了我想要的。

但我想知道,为什么请求会抛出异常而不是返回带有 NotFound 状态码的响应?

【问题讨论】:

【参考方案1】:

是的,当网页大量使用状态代码并且并非所有状态代码都是错误时,这可能会很烦人。这会使处理身体相当痛苦。我个人使用这种扩展方法来获取响应。

public static class HttpWebResponseExt

    public static HttpWebResponse GetResponseNoException(this HttpWebRequest req)
    
        try
        
            return (HttpWebResponse)req.GetResponse();
        
        catch (WebException we)
        
            var resp = we.Response as HttpWebResponse;
            if (resp == null)
                throw;
            return resp;
        
    

【讨论】:

虽然在 .Net Framework 作者的这个糟糕的设计选择中使用 HttpWebRequest/Response 来保存代码的工作最少,但正确的解决方案是使用 HttpClient,它不会抛出 4xx 和5xx 状态码。异常适用于特殊情况,抛出只是为了捕捉它并继续进行,就好像这样很好,而且对性能不利,特别是考虑到有更好的选择可以完全避免它。 msdn.microsoft.com/en-us/library/hh138242(v=vs.118).aspx 这似乎不是真的;我在项目中使用 HttpClient 并且当调用返回 404 状态代码的不存在的 url 时,客户端抛出异常而不是返回带有 404 状态代码的响应。使用 httpclient 是否有额外的步骤来防止这种情况? 在我的例子中,HttpClient 在 400 Bad Request 上抛出异常。 在我的例子中,AggregateException 被抛出,InnerExceptionWebException【参考方案2】:

为什么不呢?它们都是有效的设计选项,而 HttpWebRequest 就是为了这种方式工作而设计的。

【讨论】:

我想我很困惑,因为我看到的代码示例都没有考虑到这一点。许多人甚至没有尝试/捕获,我想知道我是否错过了一些东西,并且有一种方法可以在不引发异常的情况下获得状态。如果状态码旨在处理这样的状态,那么抛出整个异常似乎违反直觉 是的,当你认为“当然 xxx 测试了他放在他网站上的代码行!”时,它总是会产生有趣的结果。结果你错了:) 但微软建议尽可能避免异常,因为它会对性能产生负面影响。 msdn.microsoft.com/en-us/library/ms229009.aspx 这是我认为这不直观的另一个原因。如果响应可以捕获 404 作为状态代码,那么我认为这不应被视为异常。请求完成,它只是没有找到任何东西。 @MahmoudAl-Qudsi,我很高兴他们也没有决定返回 3xx 和 20x 的异常,只是因为您以后可以捕获它们! 404不是异常,显然不是客户端异常,而是服务器端是另一台需要处理异常的机器。而我这边的例外意味着我做错了什么!

以上是关于为啥 HttpWebRequest 会抛出异常而不是返回 HttpStatusCode.NotFound?的主要内容,如果未能解决你的问题,请参考以下文章

为啥geoip会抛出异常?

为啥 canvas.toDataURL() 会抛出安全异常?

为啥当参数为null时,postgres会抛出异常?

为啥 Android Geocoder 会抛出“服务不可用”异常?

为啥 Image.Save(Stream, ImageFormat) 会抛出异常?

为啥非空列表会抛出空指针异常?