如何在asp.net mvc中当会话状态超时完成后重定向到登录页面

27

我有一个ASP.NET MVC4应用程序,我正在实现sessionTimeout,例如:

<configuration>
  <system.web>
    <sessionState timeout="2"></sessionState>
  </system.web>
</configuration>

在认证方面:

<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="1" />
    </authentication>
  </system.web>
</configuration>

会话过期后(2分钟),我需要重定向到登录页面,但是重定向没有发生。

我该如何更改代码以便它可以重定向?


1
请查看下面的链接。它可能会对您有所帮助。登录页面网址 - RGR
3个回答

33

有一种方法是,如果会话过期,在每个操作中都必须检查其会话,如果为空,则重定向到登录页面。

但这非常繁琐。为了克服这个问题,您需要创建自己的ActionFilterAttribute,它将执行此操作,您只需要将此属性添加到每个操作方法中。

这里是覆盖ActionFilterAttribute的类。

public class SessionExpireFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = HttpContext.Current;

            // check if session is supported
            CurrentCustomer objCurrentCustomer = new CurrentCustomer();
            objCurrentCustomer = ((CurrentCustomer)SessionStore.GetSessionValue(SessionStore.Customer));
            if (objCurrentCustomer == null)
            {
                // check if a new session id was generated
                filterContext.Result = new RedirectResult("~/Users/Login");
                return;
            }

            base.OnActionExecuting(filterContext);
        }
    }

然后在代码中添加这个属性,像这样:

[SessionExpire]
public ActionResult Index()
{
     return Index();
}

这会为你完成工作。


基本上,我需要在每个控制器中创建您定义的类,并为每个操作方法提供ActionFilterAttribute,在索引方法中,我需要提供[SessionExpire]。是这样吗? - Jonathan
1
不,你只需要在你的app_start中创建那个类,并将该属性添加到操作中。 - user1006544
添加一个App_Start文件夹,然后添加一个类文件,再添加命名空间 - 'yourprojectName.App_Start',然后将我的代码复制粘贴到其中,并使用该属性。 - user1006544
正如user1006544所说,你必须自己实现CurrentCustomer和SessionStore。http://stackoverflow.com/questions/2417197/asp-net-mvc-session-usage? - Jana Weschenfelder
我在哪里需要将 "objCurrentCustomer" 设置为 Null? - Parth Akbari
显示剩余10条评论

33

我发现了一种在MVC中会话结束后重定向登录页面的非常简单的方法。我已经测试过它,这个方法可以正常工作。

简而言之,在_Layout中提前1分钟捕获会话结束并进行重定向。

我将逐步解释每一个步骤。

如果我们想让会话在30分钟后结束并重定向到登录页面,请按照以下步骤操作:

  1. 像这样更改web config(设置31分钟):

     <system.web>
        <sessionState timeout="31"></sessionState>
     </system.web>
    
  2. _Layout中添加以下JavaScript代码(当会话在结束前1分钟时,此代码将进行重定向,并计算用户上一次操作后的时间,而不是在网站上的第一次访问时间)

  3. <script>
        //session end 
        var sessionTimeoutWarning = @Session.Timeout- 1;
    
        var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
        setTimeout('SessionEnd()', sTimeout);
    
        function SessionEnd() {
            window.location = "/Account/LogOff";
        }
    </script>
    
  4. 这是我的LogOff操作,它只执行注销并重定向到登录页面

  5. public ActionResult LogOff()
    {
        Session["User"] = null; //it's my session variable
        Session.Clear();
        Session.Abandon();
        FormsAuthentication.SignOut(); //you write this when you use FormsAuthentication
        return RedirectToAction("Login", "Account");
    } 
    
  6. 我希望这段代码对你非常有用。


可能需要在任何 AJAX 调用上重置 setTimeout,因为用户可能会继续与表单交互并保持后端会话的活动状态。 - KyleMit
3
即使用户仍在工作,这也将重定向到登录页面。 - BYISHIMO Audace

6

有一个通用的解决方案:

假设您有一个名为Admin的控制器,您可以在其中放置授权用户的内容。

然后,您可以重写Admin控制器的InitializeOnAuthorization方法,并在这些方法中编写会话超时时重定向到登录页面的逻辑,如下所述:

protected override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        //lets say you set session value to a positive integer
        AdminLoginType = Convert.ToInt32(filterContext.HttpContext.Session["AdminLoginType"]);
        if (AdminLoginType == 0)
        {
            filterContext.HttpContext.Response.Redirect("~/login");
        }

        base.OnAuthorization(filterContext);
    }

Session["AdminLoginType"] 应该在哪里初始化? - Dr. MAF
@Dr.MAF 在另一个控制器下的登录页面 - Shahram Banazadeh
挽救了我的一天。谢谢。 - Shahram Banazadeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接