会话开始和操作过滤器用于会话超时处理

时间:2013-10-12 08:13:14

标签: asp.net-mvc asp.net-mvc-4 session

我有一个Windows Authentication的MVC4应用程序。用户可以键入10个视图中的任何一个的url来加载应用程序。没有特定的主页

如果用户闲置超过一分钟,我需要重定向到会话超时视图。我将配置文件中的会话超时值保持为一分钟。我创建了一个action filter来检查一个特定的会话值。此特定会话值在Session_Start的{​​{1}}中设置。

但是,当超时时间结束时,请求再次点击Global.asax并且它正在分配值。因此我的动作过滤器不会重定向到错误视图。 有哪些可能的解决方案可以解决这个问题?

的Web.Config

Session_Start

操作过滤器

<system.web>
    <!--Impersonate-->
    <identity impersonate="true"/>
        <!--Session Mode and Timeout-->
    <sessionState mode="InProc" timeout="1" />
    <authentication mode="Windows">
    </authentication>
    <authorization>
      <allow users="?" />
    </authorization>    
</system.web>

Global.asax中

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        var activeSession = session["IsActiveSession"];
        if (activeSession == null)
        {
            //Redirect
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Error/SessionTimeout");
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
    }
}

1 个答案:

答案 0 :(得分:11)

只需检查HttpContext.Current.Session.IsNewSession以查看是否为当前请求创建了新会话,而不是设置会话值并在操作过滤器中进行检查。修改你的动作过滤器,你最终会得到这样的结果:

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        if (session.IsNewSession)
        {
            //Redirect
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Error/SessionTimeout");
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }

    }
}

如果您想要获得想象并确保在为此请求创建的新会话之前有前一个会话,您可以更新if语句以检查是否随请求一起发送了旧会话cookie :

string cookieHeader = filterContext.HttpContext.Request.Headers["Cookie"];
if (session.IsNewSession && cookieHeader != null && cookieHeader.IndexOf("ASP.NET_SessionId") >= 0)
{
    ...
}

但是因为看起来你正在将它们发送到登录页面,所以这可能不是你必须担心的事情。如果您使用此检查,请注意此代码采用默认的"ASP.NET_SessionId" cookie名称;这可以在您的web.config中更改,在这种情况下,您需要使用新的cookie名称或get the cookie name programmatically更新IndexOf参数。