System.Net.Http.HttpClient缓存行为

我正在使用NuGet的HttpClient 0.6.0。

我有以下C#代码:

var client = new HttpClient(new WebRequestHandler() { CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable) }); client.GetAsync("http://myservice/asdf"); 

该服务(这次是CouchDB)返回ETag值和状态代码200 OK。 返回一个Cache-Control标头,其值为must-revalidate

更新,这是来自couchdb的响应头(取自visual studio调试器):

 Server: CouchDB/1.1.1 (Erlang OTP/R14B04) Etag: "1-27964df653cea4316d0acbab10fd9c04" Date: Fri, 09 Dec 2011 11:56:07 GMT Cache-Control: must-revalidate 

下次我执行完全相同的请求时,HttpClient会执行条件请求并返回304 Not Modified。 哪个是对的。

但是,如果我使用具有相同CachePolicy的低级HttpWebRequest类,则第二次甚至不会发出请求。 这是我希望HttpClient也表现的方式。

它是必须重新validation的标头值还是为什么HttpClient表现不同? 我想只做一个请求,然后在没有条件请求的情况下从缓存中获取其余的请求。

(另外,作为附注,在调试时,响应状态代码显示为200 OK,即使服务返回304 Not Modified)

两个客户端都表现正常。

must-revalidate仅适用于陈旧的响应 。

当一个缓存接收到的响应中存在must-revalidate指令时,该缓存必须在该条目变为陈旧以响应后续请求而不首先使用源服务器重新validation它之后才使用该条目。 (即, 如果仅基于原始服务器的Expires或max-age值, 缓存的响应是陈旧的 ,则缓存必须每次都进行端到端的重新validation。)

由于您未提供明确的过期, 因此允许缓存使用启发式方法来确定新鲜度 。

由于您未提供Last-Modified高速缓存,因此无需警告客户端已使用启发式扫描。

如果响应中没有Expires,Cache-Control:max-age或Cache-Control:s-maxage(请参阅第14.9.3节),并且响应不包含对缓存的其他限制, 则缓存可以计算新鲜度使用启发式的生命 。 如果尚未添加此类警告,缓存必须将警告113附加到年龄超过24小时的任何响应。

响应年龄基于Date标头计算,因为Age不存在。

如果根据启发式过期响应仍然是新鲜的,则高速缓存可以使用存储的响应。

一种解释是HttpWebRequest使用启发式方法,并且存在一个状态代码为200的存储响应仍然是新鲜的。

回答我自己的问题..

根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4我会说没有过期的“Cache-Control:must-revalidate”表明应该在每个资源上validation资源请求。

在这种情况下,它意味着每次创建资源时都应该进行条件GET。 所以在这种情况下,System.Net.Http.HttpClient表现正常,遗留(Http)WebRequest正在执行无效行为。