【问题标题】:How can I redirect to a page when the user session expires?用户会话到期时如何重定向到页面?
【发布时间】:2008-09-26 15:44:19
【问题描述】:

我目前正在开发一个使用 ASP.NET 2.0 框架的 Web 应用程序。当用户会话过期时,我需要重定向到某个页面,比如 SessionExpired.aspx。项目中有很多页面,因此在站点的每个页面中添加代码并不是一个好的解决方案。不过我有 MasterPages,我认为这可能会有所帮助。

谢谢!

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    您可以在 Session_Start 事件中的 global.asax 中处理此问题。您可以在那里检查请求中的会话 cookie。如果会话 cookie 存在,则会话已过期:

       public void Session_OnStart()
        {
            if (HttpContext.Current.Request.Cookies.Contains("ASP.NET_SessionId") != null)
            {
                HttpContext.Current.Response.Redirect("SessionTimeout.aspx")
            }
    
        }
    

    唉,我还没有找到任何优雅的方法来找出会话 cookie 的名称。

    【讨论】:

    • 我接受了这个答案,因为识别过期会话的关键是在处理新会话时检查会话cookie是否存在。
    • 不幸的是,没有很好的方法来获取会话 cookie 名称,因为您不能像使用 FormsAuthneticationTicket 那样执行“Session.CookieName”。我发现的最佳建议是只使用一个 appSetting 键/值来保存会话 Cookie 的名称。因此,您将设置两次,没有人喜欢这样做,但似乎是最方便的方法。只是我的两分钱。
    【解决方案2】:

    当用户“登录”时,我通常会在母版页上的 Page.Header.Controls 集合中添加一个 HtmlMeta 控件。将其设置为刷新到您的 SessionExpired.aspx 页面,并设置适当的超时长度,您就可以开始了。

    【讨论】:

    • 如果会话由于超时以外的任何其他原因而过期怎么办?这可能吗?
    • 过期意味着超时。您可能会以编程方式丢失会话 (Session.Abandon()),或者如果用户篡改或删除了他们的会话 cookie,但此时会话本身并没有真正过期。也许我没有完全理解这个问题......
    • 如果用户在同一个页面上花费大量时间做使用 ajax 而不是标准 GET/POST 的东西怎么办?使用这种方法,他们仍然可能会被注销。
    【解决方案3】:

    如果我理解正确,“Session_End”会在内部触发并且没有与之关联的 HTTP 上下文:

    http://forums.asp.net/t/1271309.aspx

    因此,我认为您不能使用它来重定向用户。我看到其他人建议在 global.ascx 文件中使用“Session_OnStart()”事件:

    http://forums.asp.net/p/1083259/1606991.aspx

    我没有尝试过,但是将以下代码放入“global.ascx”可能对你有用:

    void Session_OnStart() {
        if (Session.IsNewSession == false )
        {
        }
        else 
        {
            Server.Transfer("SessionExpired.aspx", False);
        }
    }
    

    【讨论】:

      【解决方案4】:

      我们使用Forms Authentication,在Page_Load方法中调用这个方法

      private bool IsValidSession()
          {
              bool isValidSession = true;
              if (Context.Session != null)
              {
                  if (Session.IsNewSession)
                  {
                      string cookieHeader = Request.Headers["Cookie"];
                      if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                      {
                          isValidSession = false;
                          if (User.Identity.IsAuthenticated)
                              FormsAuthentication.SignOut();
                          FormsAuthentication.RedirectToLoginPage();
                      }
                  }
              }
              return isValidSession;
          }
      

      【讨论】:

        【解决方案5】:

        另一种方法是告诉浏览器在一定时间后重定向自身(通过 javascript)......但用户总是可以禁用它。

        【讨论】:

          【解决方案6】:

          会话到期时您无法重定向用户,因为没有浏览器请求重定向:

          • 如果用户在会话超时(默认为 20 分钟)内访问您的站点,则会话尚未结束,因此您无需重定向。
          • 如果用户在会话超时后访问您的站点,则会话已经结束。这意味着它们将在新会话的上下文中 - Session_OnEnd 已经为旧会话触发,而您将获得新会话的 Session_OnStart。

          因此,除了客户端功能(例如 JavaScript 计时器等)之外,您还需要在 Session_OnStart 中处理重定向 - 但显然您需要将其与重新访问该站点的人区分开来。一种选择是在会话开始时设置会话 cookie(即没有过期的 cookie,因此它只会持续到浏览器关闭),然后在 Session_OnStart 中查找该 cookie - 如果它存在,它是一个过期的返回用户会话,如果不是,它是一个新用户。

          显然,您仍然可以使用 Session_OnEnd 在服务器端进行整理 - 这只是您无法使用的客户端交互。

          【讨论】:

            【解决方案7】:

            您是否在 Session 对象中放置了应该始终存在的东西?换句话说,如果他们登录,您可能会在会话中放入类似 UserID 的内容

            Session("UserID") = 1234
            

            因此,如果是这种情况,那么您可以在母版页中的代码隐藏中添加一些内容以检查该值。像这样的:

            Dim UserID As Integer = 0
            Integer.TryParse(Session("UserID"), UserID)
            
            If UserID = 0 Then
              Response.Redirect("/sessionExpired.aspx")
            End If
            

            【讨论】:

            • 嗯......这几乎可以工作。但我有一个问题。用户不登录。而是使用 Windows 身份验证。无论如何,当我找到最终解决方案时,我正在使用此解决方案并重定向到主页。
            【解决方案8】:

            您也可以查看以下链接中提供的解决方案

            Detecting Session Timeout And Redirect To Login Page In ASP.NET

            【讨论】:

              【解决方案9】:

              添加或更新您的 Web.Config 文件以包含此内容或类似内容:

              <customErrors defaultRedirect="url" mode="RemoteOnly">
                  <error statusCode="408" redirect="~/SessionExpired.aspx"/>
              </customErrors>
              

              【讨论】:

                【解决方案10】:

                您是希望在下一个请求时重定向,还是立即重定向,而无需用户干预?如果您希望在没有用户干预的情况下进行重定向,那么您可以在母版页上使用 ClientScript.RegisterStartupScript 来注入一些 javascript,以便在会话到期时重定向您的客户。

                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    String timeoutPage = "SessionExpired.aspx"; // your page here
                    int timeoutPeriod = Session.Timeout * 60 * 1000;
                
                    sb.AppendFormat("setTimeout(\"location.href = {0};\",{1});", timeoutPage, timeoutPeriod);
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "timeourRedirect", sb.ToString(), true);
                

                【讨论】:

                  【解决方案11】:

                  Code from here

                  namespace PAB.WebControls
                  

                  { 使用系统; 使用 System.ComponentModel; 使用 System.Web; 使用 System.Web.Security; 使用 System.Web.UI;

                  [DefaultProperty("Text"),
                  
                      ToolboxData("<{0}:SessionTimeoutControl runat=server></{0}:SessionTimeoutControl>")]
                  
                  public class SessionTimeoutControl : Control
                  {
                      private string _redirectUrl;
                  
                      [Bindable(true),
                          Category("Appearance"),
                          DefaultValue("")]
                      public string RedirectUrl
                      {
                          get { return _redirectUrl; }
                  
                          set { _redirectUrl = value; }
                      }
                  
                      public override bool Visible
                      {
                          get { return false; }
                  
                      }
                  
                      public override bool EnableViewState
                      {
                          get { return false; }
                      }
                  
                      protected override void Render(HtmlTextWriter writer)
                      {
                          if (HttpContext.Current == null)
                  
                              writer.Write("[ *** SessionTimeout: " + this.ID + " *** ]");
                  
                          base.Render(writer);
                      }
                  
                  
                      protected override void OnPreRender(EventArgs e)
                      {
                          base.OnPreRender(e);
                  
                          if (this._redirectUrl == null)
                  
                              throw new InvalidOperationException("RedirectUrl Property Not Set.");
                  
                          if (Context.Session != null)
                          {
                              if (Context.Session.IsNewSession)
                              {
                                  string sCookieHeader = Page.Request.Headers["Cookie"];
                  
                                  if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                                  {
                                      if (Page.Request.IsAuthenticated)
                                      {
                                          FormsAuthentication.SignOut();
                                      }
                  
                                      Page.Response.Redirect(this._redirectUrl);
                                  }
                              }
                          }
                      }
                  }
                  

                  }

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-04-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多