30

当 Web 服务器HttpWebRequest.GetResponse()使用 HTTP 304(未修改)响应时,GetResponse()会出现 a WebException,这对我来说非常奇怪。这是设计使然还是我在这里遗漏了一些明显的东西?

4

5 回答 5

48

好的,这似乎是一种设计行为,是令人烦恼的异常的完美示例。这可以通过以下方式解决:

public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
    try
    {
        return (HttpWebResponse) request.GetResponse();
    }
    catch (WebException ex)
    {
        if(ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError)
            throw; 

        return (HttpWebResponse)ex.Response;
    }
}
于 2009-09-02T10:17:04.363 回答
7

这确实是一个令人沮丧的问题,可以通过使用以下扩展方法类并调用 request.BetterGetResponse() 来解决

//-----------------------------------------------------------------------
//
//     Copyright (c) 2011 Garrett Serack. All rights reserved.
//
//
//     The software is licensed under the Apache 2.0 License (the "License")
//     You may not use the software except in compliance with the License.
//
//-----------------------------------------------------------------------

namespace CoApp.Toolkit.Extensions {
    using System;
    using System.Net;

    public static class WebRequestExtensions {
        public static WebResponse BetterEndGetResponse(this WebRequest request, IAsyncResult asyncResult) {
            try {
                return request.EndGetResponse(asyncResult);
            }
            catch (WebException wex) {
                if( wex.Response != null ) {
                    return wex.Response;
                }
                throw;
            }
        }

        public static WebResponse BetterGetResponse(this WebRequest request) {
            try {
                return request.GetResponse();
            }
            catch (WebException wex) {
                if( wex.Response != null ) {
                    return wex.Response;
                }
                throw;
            }
        }
    }
}

您可以在我关于此主题的博客文章中了解更多信息,网址为http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/

于 2011-09-03T00:41:54.577 回答
5

避免这种情况的方法System.WebException是将 AllowAutoRedirect属性设置为false。这将禁用WebRequest. 304 重定向请求似乎被破坏了,因为它不是最严格意义上的真正重定向。当然,这意味着3xx必须手动处理其他重定向请求。

于 2013-12-18T10:24:59.577 回答
2

仅供参考,这是对Anton Gogolev使用 C#6 (VS2015)when子句的答案的更新。使用调试器时会少一些烦人,因为它会删除一个捕获点:

public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
    try
    {
        return (HttpWebResponse) request.GetResponse();
    }
    catch (WebException ex)
        when (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
    {
        return (HttpWebResponse) ex.Response;
    }
}
于 2017-08-08T03:15:13.887 回答
0

我也遇到了这个问题的代码:

try
{
    ...
    var webResponse = req.GetResponse();
    ...
}
catch (WebException ex)
{
    Log.Error("Unknown error occured", ex);
    //throw; 
}

并且看来,如果远程服务器返回 304 状态,则必须通过抛出此错误或返回自定义 304 将其传递给浏览器,以便浏览器可以返回缓存的响应。否则,您可能会从远程服务器获得空响应。

所以在我的情况下,对于正确的缓存处理的正常行为,它应该是这样的:

try
{
    ...
    var webResponse = req.GetResponse();
    ...
}
catch (WebException ex)
{
    if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
        throw;
    Log.Error("Unknown error occured", ex);
}
于 2016-06-08T13:26:22.203 回答