.Net MVC - 仅为私人页面显示“会话已过期”

时间:2013-07-10 22:18:04

标签: asp.net-mvc-4 session

我正在开发一个.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中仅为“私人”页面完成“会话过期”的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

正如您所说,理想的是使用属性。更确切地说,此属性名为“Action Filter”。

您可以创建实现接口的ActionFilter,或继承现有接口。

在您的情况下,我认为获得结果的最简单方法是继承AuthorizeAttribute,并覆盖其OnAuthorization方法。

在此方法中,您可以访问HttpContext作为filterContext参数的属性:filterContext.HttpContext。您可以检查会话,授权,并检查它是否是使用此属性的ajax请求。如果需要重定向,则必须通过设置filterContext参数:

的属性来执行此操作
filterContext.Result = new RedirectResult("...url to redirect to...");

您可以使用RedirectResultRedirectToRouteResult构造函数的任何重载。

如果您保持Result属性不变,则不会发生任何特殊情况。

您可以使用此自定义属性而不是原始授权属性。