ASP.net MVC中的会话结束

10
我将用户数据放在会话中,然后将其传递给ViewData以在页面上查看。现在,当我的用户离开电脑一段时间后,会话结束并且他输入的数据会丢失。(这没关系)问题是,当他回来刷新屏幕时,我的页面仍然显示,但所有数据都丢失了。因此,

如何在会话过期时将用户重定向到登录屏幕(以便他不会看到空白页面),或者我想将他重定向到一个页面,上面写着“由于长时间未操作,您已注销”。
谢谢
4个回答

16

我在我的MasterPage中使用了一些Javascript来重定向用户(在提示续订会话后)到注销操作。它使用一个AJAX请求返回应用程序主页以刷新服务器端会话窗口,当用户点击对话框中的按钮来延长会话时。依赖于jQuery和jQuery UI来创建对话框。

 <% if (this.Request.IsAuthenticated)
    {
        int sessionDialogWait = 2 * 60 * 1000 - 60 * 500; // ms = 1.5 minutes
        int sessionTimeout = 28 * 60 * 1000; // ms = 28 minutes
        if (ViewData["sessionTimeout"] != null)
        {
            sessionTimeout = ((int)ViewData["sessionTimeout"] * 60 - 120) * 1000;
        }
%>  
<script type="text/javascript">
    var logoutTimer = null;
    var sessionTimer = null;
    var sessionTimeout = Number('<%= sessionTimeout %>');
    var sessionDialogWait = Number('<%= sessionDialogWait %>');

    $(document).ready( function() {
        $('#sessionEndDialog').dialog( {
            autoOpen: false,
            bgiframe: true,
            modal: true,
            buttons: {
                OK: function() {
                    $(this).dialog('close');
                    $.get( '<%= Url.Action( "About", "Home" ) %>', scheduleSessionPrompt, 'html' );
                },
                Logout: logoutOnSessionExpires
            }
        }).ajaxStart( function() { scheduleSessionPrompt(); } );
        scheduleSessionPrompt();
    });

    function scheduleSessionPrompt()
    {
        if (logoutTimer) clearTimeout(logoutTimer);
        if (sessionTimer) clearTimeout(sessionTimer);

        sessionTimer = setTimeout( sessionExpiring, sessionTimeout  );
    }

    function sessionExpiring()
    {
         logoutTimer = setTimeout( logoutOnSessionExpires, sessionDialogWait );
         $('#sessionEndDialog').dialog('open');
    }

    function logoutOnSessionExpires()
    {
        window.location.href = '<%= Url.Action( "Logout", "Account" ) %>';
    }       

    </script>
<% } %>

<div id="sessionEndDialog" title="Session Expiring" style="display: none;">
    <p>Your session is about to expire.  Click OK to renew your session or Logout to logout of the application.</p>
</div>

Global.asax 中的 Session_End 可以用来做这个吗? - Tony Borf
我不明白如何在Session_End事件中将浏览器重定向到另一个页面,除非浏览器定期检查会话是否仍然存在。不幸的是,让浏览器执行此操作将人为地保持会话活动状态,因为它将在每次查询时更新。我正在努力将其转化为jQuery插件。 - tvanfosson
如果我错了,请纠正我,但是Session_End在后台线程中运行,因此无法与用户通信。tvanfosson,喜欢你的工作,你的方法非常有效。 - CodeKiwi

7

我曾经在一个旧的ASP.net应用程序中遇到过同样的问题。会话过期,但用户仍然被认证,因为会话和身份验证cookie是不同的,不一定在同一时间过期。 当时我所做的是使用global.asax中的Session_Start检查用户是否已经认证,并将其注销。

    protected void Session_Start(Object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated)
        {
            FormsAuthentication.SignOut();
            Response.Redirect("~/SessionEnd.aspx");
        }
    }

这会强制启动会话的用户重新登录。您还可以使用此事件从数据库中恢复会话信息,或者将其重定向到另一个页面,但保持他的凭据有效。


会话超时是Web服务器的功能吗?(IIS6)它只能从控制面板中更改吗? 会话超时是否为Web服务器功能取决于具体实现。在IIS6中,可以通过控制面板更改会话超时设置。 - Tony Borf
我尝试了这段代码,它让我退出了,但是 Response.Redirect 没有将我带到我的页面。 - Tony Borf
您可以在web.config文件中更改会话过期时间: <sessionState mode="InProc" timeout="100"/> 或者通过编程方式使用Session.Timeout = x;如果您注销,则只能访问登录页面或未受身份验证保护的页面。 - Ariel Popovsky

6
我假设您正在以某种方式对用户进行身份验证,但是您是否使用Forms身份验证?: ASP.Net MVC框架-使用Forms身份验证 如果您已经在使用Forms身份验证,则需要确保身份验证cookie的过期时间比会话超时时间短一点。

是的,我正在使用默认的MVC项目作为我的基础。 - Tony Borf
呸!我讨厌网站总是让我退出登录。在实施此功能之前请仔细考虑。当然,你的网站性质将是决定因素 :) - Simon_Weaver

0

数据可能仍然在页面上,因为浏览器正在缓存它。

尝试将其放入其中,看看会话结束后数据是否仍然存在:

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

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