【问题标题】:Session Timeout Doesn't Hit the Action Filter会话超时未命中操作过滤器
【发布时间】:2019-01-12 23:29:30
【问题描述】:

我在 Startup.Auth.cs 中启用了会话超时:

 app.UseCookieAuthentication(new CookieAuthenticationOptions
 {
       ExpireTimeSpan = TimeSpan.FromMinutes(1)
 }

将其设置为 1 分钟以进行测试。现在我创建了一个动作过滤器:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext ctx = HttpContext.Current;


        base.OnActionExecuting(filterContext);
    }
}

并通过添加filters.Add(new SessionExpireFilterAttribute()); 将其注册到FilterConfig.cs。我还在customercontroller 类上放置了属性[SessionExpireFilter]

现在发生的情况是,如果我在会话过期时单击向操作 customer/edit 发送请求的按钮,代码确实会在 customercontroller constructor 中遇到断点,然后返回 200 .它永远不会到达 actionfilter 中的断点。它也从来没有达到实际行动edit

有什么想法吗?

谢谢。

【问题讨论】:

  • 您似乎在错误的位置进行调试。它是否在任何其他地方遇到断点?
  • 并非如此。它去那里然后处理一些 dbcontext/EF 对象。
  • 我的意思是:尝试在其他地方设置断点并检查是否可以命中它。例如在app.UseCookieAuthentication(...)处设置断点。
  • 是的。 app.UseCookieAuthentication(...) 在应用程序启动时被命中。然后在会话到期之前正确命中所有控制器/操作和过滤器操作。如果我在会话有效时点击了按钮,则会点击操作过滤器中的断点。但是如果我离开它一分钟左右,然后点击按钮,它只会转到控制器的构造函数并返回 200。
  • 然后它看起来像一个缓存。您的响应是否包含Cache-Control HTTP 标头?

标签: c# asp.net-mvc httpsession


【解决方案1】:

从 HTTP 标头中删除 Cache-Control

在 MVC 中防止缓存,我们创建了自己的属性,您也可以这样做。这是我们的代码:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

然后用 [NoCache] 装饰你的控制器。或者,您可以将属性放在继承控制器(如果有的话)的基类的类上,就像我们在这里一样:

[NoCache]
public class ControllerBase : Controller, IControllerBase

如果你需要一些动作是不可缓存的,你也可以用这个属性装饰一些动作,而不是装饰整个控制器。

或者你可以使用内置的缓存属性来防止缓存。

.net 框架:[OutputCache(NoStore = true, Duration = 0)]

.net 核心:[ResponseCache(NoStore = true, Duration = 0)]

【讨论】:

  • 非常感谢您的回复。这帮助很大。
猜你喜欢
  • 2013-10-20
  • 2016-10-14
  • 1970-01-01
  • 2020-04-25
  • 2015-05-22
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多