ASP.NET MVC 使用 SessionState 确定剩余会话超时

YuM*_*Mei 6 asp.net ajax session-state session-timeout asp.net-mvc-4

在我的一个 Web 应用程序中,我需要在 5 分钟内会话超时时弹出警报。用户可以选择继续延长会话或立即注销。

在 Web.config 中将会话超时设置为 30 分钟:

<sessionState mode="InProc" timeout="30">
Run Code Online (Sandbox Code Playgroud)

由于 ASP.NET MVC 没有提供检查剩余会话超时的方法,我提出了如下解决方案:

在 Global.asax 中,它将当前会话的上次访问时间作为会话变量进行跟踪。如果传入请求不是只读会话状态(见下文),则上次访问时间会话变量将更新为当前时间。否则,会话变量的值将设置为当前时间。

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    var context = HttpContext.Current;
    if (context != null && context.Session != null && !context.Session.IsReadOnly)
    {
        context.Session["_LastAccessTime"] = DateTime.Now;
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的会话控制器中,我将会话状态行为设置为只读。对此控制器的请求既不会重置会话,也不会刷新我的上次访问时间会话变量

[SessionState(SessionStateBehavior.ReadOnly)]
public class SessionController : BaseController
{
    [AjaxOnly]
    public ActionResult GetRemainingSessionTimeout()
    {
        if (!Request.IsAjaxRequest())
        {
            return Content("Not an Ajax call.");
        }

        var remainingSessionTimeout = 0;
        if (Session["_LastAccessTime"] != null)
        {
            var lastAccessTime = (DateTime) Session["_LastAccessTime"];
            var timeSpan = DateTime.Now.Subtract(lastAccessTime);
            remainingSessionTimeout = Session.Timeout - timeSpan.Minutes;
        }

        return Json(new {RemainingSessionTimeout = remainingSessionTimeout}, JsonRequestBehavior.AllowGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

在视图中,Ajax 请求会默默地检查剩余会话超时。如果少于5分钟,则弹出警报:

$(document).ready(function () {
    $("#remainingSessionTimeout").click(function (e) {
        var url = '@Url.Action("GetRemainingSessionTimeout", "Session", new { area = "" })';
        $.ajax({
            type: "POST",
            url: url,
            data: {},
            success: function (result) {
                $("#timeoutLeft").html('Your session expries in ' + result.Timeout * 60 + ' seconds.');
            },
            error: function (result) {
                $("#timeoutLeft").html('error in getting session data.');
        }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

该解决方案有什么缺点或缺陷吗?谢谢。