vto*_*ola 11 asp.net caching outputcache http asp.net-mvc-3
我有一个我想要缓存的动作方法:
[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="index")]
public ActionResult Index()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
用这种方法:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.VaryByHeaders["Cookie"] = true;
if (User.Identity.IsAuthenticated)
{
Debug.Print("Authenticated");
context.Response.Cache.SetNoServerCaching();
context.Response.Cache.SetCacheability(HttpCacheability.Private);
return null;
}
else
{
Debug.Print("Non authenticated");
return custom;
}
}
Run Code Online (Sandbox Code Playgroud)
我们的想法是为未经过身份验证的用户保留页面的缓存版本,但避免对经过身份验证的用户进行缓存.
我以为它总会返回Vary:CookieHTTP标头,但事实并非如此.使用Fiddler进行测试并发出两次相同的请求,在第一次HTTP调用中它很顺利:
HTTP/1.1 200 OK
Cache-Control: public, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: Cookie
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:37 GMT
Content-Length: 441
Run Code Online (Sandbox Code Playgroud)
但在第二个中,它会覆盖标题:
HTTP/1.1 200 OK
Cache-Control: public, max-age=297
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:39 GMT
Content-Length: 441
Run Code Online (Sandbox Code Playgroud)
因此,据我所知,浏览器即使是公共的,也不会缓存请求,因为这Vary:*意味着请求是使用不在URL中的参数生成的,也不是在HTTP标头中生成的.有没有办法来解决这个问题?
问候.
更新:
以类似的方式,当我发送两个相同的经过身份验证的请求时,第一个调用获取private修饰符,但不获取Vary标题:
HTTP/1.1 200 OK
Cache-Control: private, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:43:14 GMT
Last-Modified: Thu, 09 Feb 2012 12:38:14 GMT
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:38:14 GMT
Content-Length: 443
Run Code Online (Sandbox Code Playgroud)
但第二个获得与未经过身份验证的请求相同的响应:
HTTP/1.1 200 OK
Cache-Control: public, max-age=298
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:44:32 GMT
Last-Modified: Thu, 09 Feb 2012 12:39:32 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:39:33 GMT
Content-Length: 443
Run Code Online (Sandbox Code Playgroud)
请注意,IHttpModule根据请求是否有cookie ,有一个设置是否经过身份验证的请求,这不是"现实生活"方法,仅用于测试目的.
该项目仅包含一个带有自身链接的网页,一个登录您的链接以及另一个将您注销的链接:
HTTP 302再次将cookie 重定向到主页.HTTP 302再次将重定向的过期cookie发送到主页.该预期/理想的行为将是:
但到目前为止这是行为:
Vary在经过身份验证的响应中缺少标头.我不知道我是否对缓存有什么不妥,只是遗漏了一些细节或者OutputCache工作不是很好,但我会很感激任何指导.
干杯.
更新2:
我的目的是使用HTTP缓存语义来:
如果我更改OutputCache声明仅在服务器上执行缓存并阻止下游和客户端缓存:
[OutputCache(Duration=60*5, Location=OutputCacheLocation.Server, VaryByCustom="index")]
Run Code Online (Sandbox Code Playgroud)
它的行为与预期的一样,但是防止了下游和客户端缓存,这不是我想要的.
我不认为该[OutputCache]属性是您想要的,该VaryByCustom方法基本上是说我想根据这些参数缓存不同的版本,它实际上没有“不缓存”选项以及属性中的大部分代码围绕基于服务器的缓存构建。
话虽这么说, MSDN上的自定义缓存文档似乎表明您需要返回一个字符串,以根据身份验证状态进行更改:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if(custom == "user") return "User:" + context.Request.User.Identity.Name;
return base.GetVaryByCustomString(context, custom);
}
Run Code Online (Sandbox Code Playgroud)
然后在以下位置使用用户文字VaryByCustom:
[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="user")]
public ActionResult Index()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
所以基本上这会导致为匿名(假设匿名身份是空字符串或其他东西)和服务器上的每个用户构建一个缓存,并发Vary: *送到我相信的客户端。显然不理想你正在寻找什么。
如果您确实只想使用 HTTP 缓存来缓存未经身份验证的版本,我建议不要使用OutputCacheAttribute并使用更自定义的内容。
您可以轻松地在自己的自定义属性中编写类似于您的GetVaryByCustomString实现的内容(这只是一些伪代码,需要的不仅仅是这个):
public class HttpCacheUnauthenticatedAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if(!filterContext.HttpContext.Request.IsAuthenticated) {
//TODO: set unauthenticated caching values and vary here
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后用它标记你的操作方法:
[HttpCacheUnauthenticated]
public ActionResult Index()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2884 次 |
| 最近记录: |