我在asp.mvc中注销时遇到问题。 用户可以按回按钮,他将看到上次访问的页面。
我进行了一些搜索并找到了这样的解决方案:
this.Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
this.Response.Cache.SetNoStore();
但是我应该将它添加到每个页面以使其正常工作。
是否有某种方法可以为mvc应用程序中的所有控制器的所有GET请求禁用缓存,然后为其中一些控制器启用缓存,例如使用属性或自定义过滤器?
答案 0 :(得分:3)
让它在全球范围内运作并不是很重要。我在过去所做的是创建一个派生自ActionFilter的类,然后将其添加为global.asax中的全局动作过滤器。另请注意,实际强制所有浏览器重新加载并非易事。即使是下面的代码并不总是适用于Safari,它通常必须通过body标签或类似的空载件进行欺骗。
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
/// <summary>
/// Action filter that instructs the page to expire.
/// </summary>
public class PageExpirationAttribute : ActionFilterAttribute
{
/// <summary>
/// The OnActionExecuted method.
/// </summary>
/// <param name="filterContext">The current ActionExecutedContext. </param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
filterContext.HttpContext.Response.ClearHeaders();
filterContext.HttpContext.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate, post-check=0, pre-check=0, max-age=0");
filterContext.HttpContext.Response.AppendHeader("Pragma", "no-cache");
filterContext.HttpContext.Response.AppendHeader("Keep-Alive", "timeout=3, max=993");
filterContext.HttpContext.Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
}
}
如果您希望能够排除某些页面,则可以创建另一个可应用于控制器或方法的属性。您的OnActionExecuting()可以检查属性是否存在:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AllowCachingAttribute : Attribute
{
}
要添加到OnActionExecuting的近似代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
/// <summary>
/// Action filter that instructs the page to expire.
/// </summary>
public class PageExpirationAttribute : ActionFilterAttribute
{
/// <summary>
/// The OnActionExecuted method.
/// </summary>
/// <param name="filterContext">The current ActionExecutedContext. </param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
bool skipCache = filterContext.ActionDescriptor.IsDefined(typeof(AllowCachingAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowCachingAttributee), true);
if (!skipCache)
{
filterContext.HttpContext.Response.ClearHeaders();
filterContext.HttpContext.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate, post-check=0, pre-check=0, max-age=0");
filterContext.HttpContext.Response.AppendHeader("Pragma", "no-cache");
filterContext.HttpContext.Response.AppendHeader("Keep-Alive", "timeout=3, max=993");
filterContext.HttpContext.Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
}
}
}
答案 1 :(得分:0)
您可以创建一个Utilities类并添加一个公共静态方法来执行上面的代码然后调用它。然后在控制器的方法中,调用Utilities方法。我将提供一些代码:
namespace App
{
public class Utility
{
public static void SetResponsAttributes(HttpResponseBase theResponseObject)
{
if (theResponseObject == null) return;
theResponseObject.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));
theResponseObject.Cache.SetCacheability(HttpCacheability.NoCache);
theResponseObject.Cache.SetNoStore();
}
}
}
答案 2 :(得分:0)
为什么不设置会话标志以指示登录指示符并将整个视图内容包装在if块中。在退出时放弃会话。