介绍问题
如果服务器指示304 Not Modified,我们已成功配置浏览器缓存以返回已保存的响应.这是配置:
<caching> <outputCacheSettings> <outputCacheProfiles> <add name="TransparentClient" location="Client" duration="0" /> </outputCacheProfiles> </outputCacheSettings> </caching>
web.config是完美的,并设置Cache-control:private,max-age = 0,以便:
>浏览器将缓存响应,
>将始终验证缓存,并且
>如果服务器响应304,将返回缓存的响应.
问题是我们的MVC.NET动作总是响应200而不是304.
问题
当ActionResult没有改变时,我们如何配置输出缓存以返回304 Not Modified?
> MVC.NET中是否有内置的缓存验证?
>如果不是,我们如何推出自己的缓存验证机制?
roll-our-own可能需要一个带ETag或Last-Modified的Action Filter.
屏幕截图
这是一个Fiddler截图,显示缺少304.
> 318是SHIFT刷新.
> 332是一个我们预期会导致304的刷新.问题.
搜索和研究
ASP.NET MVC : how do I return 304 “Not Modified” status?提到从Action中返回304.这并没有提供使OutputCache准确响应304的方法.
Working with the Output Cache and other Action Filters显示了如何覆盖OnResultExecuted,这将允许添加/删除标头.
解决方法
以下内容适用于我们.
Web.Config中
设置Cache-Control:private,max-age-0以启用缓存并强制重新验证.
<system.web> <caching> <outputCacheSettings> <outputCacheProfiles> <add name="TransparentClient" duration="0" location="Client" /> </outputCacheProfiles> </outputCacheSettings> </caching> </system.web>
行动
[MyOutputCache(CacheProfile="TransparentClient")] public ActionResult ValidateMe() { // check whether the response is modified // replace this with some ETag or Last-Modified comparison bool isModified = DateTime.Now.Second < 30; if (isModified) { return View(); } else { return new HttpStatusCodeResult(304,"Not Modified"); } }
过滤
删除Cache-Control:private,max-age-0否则缓存将存储状态消息.
public class MyOutputCache : OutputCacheAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { base.OnResultExecuted(filterContext); if (filterContext.HttpContext.Response.StatusCode == 304) { // do not cache the 304 response filterContext.HttpContext.Response.CacheControl = ""; } } }
Fidder酒店
Fiddler表明缓存行为正常.