Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 启用缓存的HttpWebRequest引发异常_C#_Httpwebrequest - Fatal编程技术网

C# 启用缓存的HttpWebRequest引发异常

C# 启用缓存的HttpWebRequest引发异常,c#,httpwebrequest,C#,Httpwebrequest,我正在开发一个小型的C#/WPF应用程序,该应用程序使用手工编制的HttpWebRequest调用和JSON序列化与rubyonrails中实现的web服务进行接口。在没有缓存的情况下,一切都能正常工作,我还可以使用HTTP身份验证和压缩 启用缓存后,通过设置request.CachePolicy=new-HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable),出现问题-在生产环境中。当连接到一个简单的WEBrick实例时,一

我正在开发一个小型的C#/WPF应用程序,该应用程序使用手工编制的
HttpWebRequest
调用和JSON序列化与rubyonrails中实现的web服务进行接口。在没有缓存的情况下,一切都能正常工作,我还可以使用HTTP身份验证和压缩

启用缓存后,通过设置
request.CachePolicy=new-HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable),出现问题-在生产环境中。当连接到一个简单的WEBrick实例时,一切正常,我得到了
HTTP/1.1 304未按预期修改的
,并且
HttpWebRequest
提供了缓存的内容

当我在生产服务器上运行nginx/0.8.53+Phusion-Passenger 3.0.0时,应用程序崩溃。第一个请求(未缓存)得到了正确的服务,但是在第二个请求(导致304响应)上,我得到一个
WebException
声明“请求被中止:请求被取消。”只要我调用
request.GetResponse()

我已经运行了连接,这并没有帮助很大;WEBrick和nginx都返回一个空的实体体,尽管响应头不同。拦截请求并更改nginx的响应头以匹配WEBrick的响应头并没有改变任何事情,这让我认为这可能是一个保持活力的问题;设置
request.KeepAlive=false没有改变任何东西,但是-它在连接到WEBrick时不会中断内容,在连接到nginx时也不会修复内容

值得一提的是,
WebException.InnerException
是一个
NullReferenceException
,具有以下
StackTrace

at System.Net.HttpWebRequest.CheckCacheUpdateOnResponse()
at System.Net.HttpWebRequest.CheckResubmitForCache(Exception& e)
at System.Net.HttpWebRequest.DoSubmitRequestProcessing(Exception& exception)
at System.Net.HttpWebRequest.ProcessResponse()
at System.Net.HttpWebRequest.SetResponse(CoreResponseData coreResponseData)
(工作)WEBrick连接的标头:

########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testbox.local:3030
If-None-Match: "84a49062768e4ca619b1c081736da20f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
X-Ua-Compatible: IE=Edge
Etag: "84a49062768e4ca619b1c081736da20f"
Date: Wed, 01 Dec 2010 18:18:59 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-08-16)
X-Runtime: 0.177545
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: *REDACTED*
########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testsystem.local:8080
If-None-Match: "a64560553465e0270cc0a23cc4c33f9f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
Connection: keep-alive
Status: 304
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.0
ETag: "a64560553465e0270cc0a23cc4c33f9f"
X-UA-Compatible: IE=Edge,chrome=1
X-Runtime: 0.240160
Set-Cookie: *REDACTED*
Cache-Control: max-age=0, private, must-revalidate
Server: nginx/0.8.53 + Phusion Passenger 3.0.0 (mod_rails/mod_rack)
(异常引发)nginx连接的标头:

########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testbox.local:3030
If-None-Match: "84a49062768e4ca619b1c081736da20f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
X-Ua-Compatible: IE=Edge
Etag: "84a49062768e4ca619b1c081736da20f"
Date: Wed, 01 Dec 2010 18:18:59 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-08-16)
X-Runtime: 0.177545
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: *REDACTED*
########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testsystem.local:8080
If-None-Match: "a64560553465e0270cc0a23cc4c33f9f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
Connection: keep-alive
Status: 304
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.0
ETag: "a64560553465e0270cc0a23cc4c33f9f"
X-UA-Compatible: IE=Edge,chrome=1
X-Runtime: 0.240160
Set-Cookie: *REDACTED*
Cache-Control: max-age=0, private, must-revalidate
Server: nginx/0.8.53 + Phusion Passenger 3.0.0 (mod_rails/mod_rack)
更新: 我试着做一个快速而肮脏的手动ETag缓存,但结果是不行的:当调用
request.getresponse()
时,我得到一个
WebException
,告诉我“远程服务器返回了一个错误:(304)未修改。”-是的,.NET,我知道这一点,我想(尝试)自己处理它,grr

更新2: 越来越接近问题的根源。showstopper似乎与初始请求的响应头有所不同。WEBrick包含一个
日期:Wed,2010年12月1日21:30:01 GMT
标题,该标题在nginx回复中不存在。还有其他区别,但是使用fiddler截取最初的nginx回复并添加
Date
头,随后的
HttpWebRequest
s能够处理(未修改的)nginx 304回复

我们将尝试寻找解决方法,并让nginx添加日期标题

更新3: 服务器端的问题似乎与Phusion乘客有关,他们缺少
Date
标题。我仍然认为
HttpWebRequest
的行为是。。。次优

更新4:
为bug添加了一张罚单。

我认为,当“预期行为”(即获取响应主体)无法完成时,设计师们发现抛出异常是合理的。您可以通过以下方式明智地处理此问题:

catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var statusCode = ((HttpWebResponse)ex.Response).StatusCode;
        // Test against HttpStatusCode enumeration.
    }
    else
    {
        // Do something else, e.g. throw;
    }
}

因此,事实证明是Phusion Passenger(或nginx,取决于您对它的看法,也很瘦)没有添加
Date
HTTP响应头,再加上我在.NET HttpWebRequest中看到的bug(在我的情况下,如果自
以来进行了修改,则没有
,因此日期应该是不必要的),导致了问题

特殊情况的解决方法是编辑Rails应用程序控制器:

class ApplicationController < ActionController::Base
    # ...other stuff here

    before_filter :add_date_header
    # bugfix for .NET HttpWebRequst 304-handling bug and various
    # webservers' lazyness in not adding the Date: response header.
    def add_date_header
        response.headers['Date'] = Time.now.to_s
    end
end

可能值得一试,但似乎是一个特别令人讨厌的黑客行为——特别是因为(在尝试手动进行缓存时),在事件尝试获取响应流之前,我已经在GetResponse()中获得了异常。另外,如果我能让自动缓存在nginx上工作,那将是最整洁的——不过还是谢谢你:)嗨!我认为您在HttpWebRequest中发现了一个bug。您能否创建复制日志(请参阅)并在上创建错误请求?这样,微软就可以解决这个问题。@feroze:我昨天没时间了,但我已经在Connect now上添加了错误通知单。