0

我正在开发一个 .NET MVC 4 应用程序,如果用户在会话超时后执行某些操作,该应用程序需要向用户显示“会话过期”消息。

我正在使用超时时间很长的表单身份验证和超时时间较短的会话,因此我可以知道会话是否过期或者它是新访问者。这是我的 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 中的“私有”页面完成“会话过期”的最佳方法是什么?

4

1 回答 1

1

正如您所说,理想情况是使用属性。更准确地说,这个属性被命名为“动作过滤器”。

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

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

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

filterContext.Result = new RedirectResult("...url to redirect to...");

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

如果您Result保持不动,就不会发生什么特别的事情。

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

于 2013-07-11T00:13:51.773 回答