当 web 服务器用 HTTP 304(未修改)响应HttpWebRequest.GetResponse()
时,GetResponse()
会抛出WebException
异常,这对我来说非常奇怪。这是设计如此还是我漏掉了什么明显的东西?
当 web 服务器用 HTTP 304(未修改)响应HttpWebRequest.GetResponse()
时,GetResponse()
会抛出WebException
异常,这对我来说非常奇怪。这是设计如此还是我漏掉了什么明显的东西?
好的,这似乎是一个设计行为,并且是一个完美的令人烦恼的异常的例子。可以通过以下方式解决:
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;
}
}
这真的是一个令人沮丧的问题,但可以通过使用以下扩展方法类并调用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;
}
}
}
}
您可以在此处阅读有关此主题的博客文章。
博客文章涉及到it技术相关内容,并介绍了如何修复WebRequests的异常抛出问题,以便返回状态。请点击链接查看详情。
System.WebException
的方法是将AllowAutoRedirect属性设置为false
。这会禁用WebRequest
的自动重定向逻辑。对于304重定向请求,它似乎存在问题,因为它不是严格意义上的真正重定向。当然,这也意味着其他重定向请求3xx
必须手动处理。提醒一下,这是对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;
}
}
我也遇到了这个代码问题:
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);
}
|| ((HttpWebResponse) ex.Response).StatusCode != HttpStatusCode.NotModified
。 - Danny Beckettwhen
语句! - binki