会话超时后重定向到登录页面

6

我发现了一些类似的问题,但是没有给我我真正需要的答案。

事情是这样的,我已经将以下代码添加到我的 web.config 文件中,以处理用户会话过期:

<sessionState mode="InProc" timeout="1" />

1分钟后,Global.asax 中的 Session_End 事件将被触发:

Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
    Response.Redirect("Login.aspx")
End Sub

这不起作用,因为:

Response is not available in this context.

顺便提一下,这个问题得到了一个答案,表明这是可以的,并且得到了赞。

我不想要什么花里胡哨的东西。我只想要一个简单的方法,在会话时间过期时将用户重定向到登录页面。就这些。

谢谢。


尝试使用HttpContext.Current.Response.Redirect("Login.aspx")。 - Tim
如果您已经正确注册了登录信息,用户应该被重定向到任何帖子的登录页面。作为用户,我不想因为会话超时而失去当前所在的页面。 - paparazzo
那样做行不通,@Tim。无论如何还是谢谢你。 - gabsferreira
@Blam,你所说的“正确注册”的登录是什么意思? - gabsferreira
我不记得所有的步骤,但我确定我的生产应用程序是这样工作的,因为我加载数据时我的登录经常过期。如果它把我发送到另一个页面,我就看不到我的加载是否完成,我不喜欢那样。在ASP.NET中,你将其标记为登录页面,我记不清是否还需要在IIS中标记它。我记得我必须在ASP.NET项目和IIS中都标记默认页面。 - paparazzo
你正在使用MembershipServices吗?如果没有,没关系。或者考虑使用MemberShipServices。 - paparazzo
4个回答

3

描述

您可以在 global.asax 中使用 Page_Init 事件。

示例

Protected Sub Page_Init(sender As Object, e As EventArgs)
 If Context.Session IsNot Nothing Then
  If Session.IsNewSession Then
   Dim newSessionIdCookie As HttpCookie = Request.Cookies("ASP.NET_SessionId")
   If newSessionIdCookie IsNot Nothing Then
    Dim newSessionIdCookieValue As String = newSessionIdCookie.Value
    If newSessionIdCookieValue <> String.Empty Then
     ' This means Session was timed Out and New Session was started
     Response.Redirect("Login.aspx")
    End If
   End If
  End If
 End If
End Sub

更多信息


好的,我已经将这段代码复制到我的Global.asax文件中,并在其上设置了断点。当会话过期时,Session_End被触发,但Page_Init没有被触发。 - gabsferreira
是的,但在下一个请求时,该方法应该被调用。问题在于服务器知道会话已过期,但在HTTP(没有永久连接)中,您无法对客户端执行任何操作。只有当用户发出请求时,您才能执行某些操作。 - dknaack
如果您希望保持会话活动状态,可以使用JavaScript从客户端向服务器发送请求,每x秒钟发送一次。 - dknaack

3

Session_End是一个服务器端事件,意味着它在Web服务器上触发,与客户端的请求无关。这就是为什么请求不可用的原因。

在此问题中你有两个选择:

  1. 在每个客户端请求时检查是否设置了特定的Session变量。如果没有设置,那么表示前一个Session已过期,必须填充新的Session。(我假设这就是你想要检查Session过期的原因)

  2. 在客户端上使用javascript定期返回服务器以检查Session是否仍然有效。如果Session已过期,你可以将用户重定向到登录页面。

不同重定向方法的示例

location.href = "login.aspx";
// or you can use 
location.assign("login.aspx");
//for redirecting without storing in history
location.replace("login.aspx")

不要忘记在登录重定向路径中添加?ReturnUrl=[current url]

希望对你有所帮助。


4
当你使用JavaScript或其他方式从客户端向服务器发起调用时,会始终重新启动会话。因此,上述方法永远不会起作用。 - Jitendra Pancholi
它不会 更新 会话,而是创建一个新的会话。因此,如果您的先前会话已设置了标记,则新创建的会话将不会设置该标记。 - Shai Cohen
1
@ShaiCohen,您的评论直接与第二点相矛盾。如果检查间隔小于会话超时时间,则会更新现有会话的上次访问时间,并且超时将永远不可能发生,正如Jitendra所说的那样。如果您的检查间隔大于会话超时时间,则您在评论中提到的内容可能有效,但用户将无法被警告其会话即将过期; 它已经过期了。 - Caleb Adams

0

这是dknaack的答案的C#版本:

protected void Page_Init(object sender, EventArgs e)
{
    if (Context.Session != null)
    {
        if (Session.IsNewSession)
        {
            HttpCookie newSessionIdCookie = Request.Cookies["ASP.NET_SessionId"];
            if (newSessionIdCookie != null)
            {
                string newSessionIdCookieValue = newSessionIdCookie.Value;
                if (newSessionIdCookieValue != string.Empty)
                {
                    // This means Session was timed Out and New Session was started
                    Response.Redirect("Login.aspx");
                }
            }
        }
    }
}

0
在每个Page_Init事件上检查过期的会话。如果有太多页面需要进行此检查,我通常会这样做:
  • 创建一个基类并从System.Web.UI.Page继承。
  • 在我的基类的Page_Init事件中编写重定向逻辑。
  • 让我的其他页面从这个基类继承。
祝你好运。

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