我正在开发一个.NET MVC 4应用程序,如果他在会话超时后执行某些操作,则需要向用户显示“Session expiration”消息。
我正在使用具有很长超时的表单身份验证和具有较短超时的sesion,因此我可以知道会话是否过期或者是新访问者。这是我的Web.config部分:
<authentication mode="Forms">
<forms loginUrl="~/Login" timeout="10080" defaultUrl="~/Index" />
</authentication>
<sessionState mode="InProc" timeout="20" />
正如我所说,这只是为了区分新访问者和会话超时,而不是应用程序本身所必需的。如果用其他东西可以达到相同的结果,就可以改变它。
在Web.config中使用它,我可以在Global.asax中执行以下操作:
protected void Session_Start(object sender, EventArgs e)
{
//if it's a new session AND the user is authenticated, then it's a session timeout
if (Request.IsAuthenticated)
{
if (Request.RequestContext.HttpContext.Request.IsAjaxRequest())
{
//...
//Ajax handling code
//...
//The redirect is so I can return a JsonResult with a standard object with the message
Response.Redirect("/GetJson?some_parameters, true);
}
else
{
Response.Redirect("/SessionExpired", true);
}
}
}
这一切都适用于需要登录的网站的私人部分。问题是如果用户被记录,等待会话超时,然后尝试打开一个不需要登录的“公共”页面,他仍然会收到“会话已过期”消息。这就是我想要避免的。只有当用户尝试访问需要登录的页面时,才会向用户显示“会话过期”消息。
我试图在Session_Start中设置一个标志,并在以后的Global.asax事件中重定向,但它没有用,因为我有一些变量可访问性问题。
我想过尝试检查当前操作是否具有[AllowAnonymous]
属性,以便我可以跳过重定向,但我无法弄清楚如何。
我读到的一些答案给我的印象是我的“会话过期”逻辑应该是自定义属性,但我不知道这是否是正确的方法。
我的问题是,在.Net MVC 4中仅为“私人”页面完成“会话过期”的最佳方法是什么?
答案 0 :(得分:1)
正如您所说,理想的是使用属性。更确切地说,此属性名为“Action Filter”。
您可以创建实现接口的ActionFilter,或继承现有接口。
在您的情况下,我认为获得结果的最简单方法是继承AuthorizeAttribute
,并覆盖其OnAuthorization
方法。
在此方法中,您可以访问HttpContext
作为filterContext
参数的属性:filterContext.HttpContext
。您可以检查会话,授权,并检查它是否是使用此属性的ajax请求。如果需要重定向,则必须通过设置filterContext
参数:
filterContext.Result = new RedirectResult("...url to redirect to...");
您可以使用RedirectResult
或RedirectToRouteResult
构造函数的任何重载。
如果您保持Result
属性不变,则不会发生任何特殊情况。
您可以使用此自定义属性而不是原始授权属性。