当Web服务器使用HTTP 304(未修改)响应HttpWebRequest.GetResponse()
时,GetResponse()
会产生WebException
,这对我来说非常奇怪。这是设计还是我错过了一些明显的东西?
答案 0 :(得分:46)
好吧,这似乎是一种设计行为,是vexing exception的完美例子。这可以通过以下方法解决:
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;
}
}
答案 1 :(得分: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;
}
}
}
}
的关于此主题的博文中了解更多相关信息
答案 2 :(得分:3)
避免此System.WebException
的方法是设置
AllowAutoRedirect属性false
。
这会禁用WebRequest
的自动重定向逻辑。对于304重定向请求似乎已被打破,因为它不是最严格意义上的真正重定向。
当然,这意味着必须手动处理其他重定向请求3xx
。
答案 3 :(得分:2)
正如一个FYI,这是对使用C#6(VS2015)when
子句的Anton Gogolev's answer的更新。使用调试器时它不那么烦人,因为它删除了一个catchpoint:
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;
}
}
答案 4 :(得分: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);
}