Session Start and Action Filter for Session Timeout handling

18,174

Instead of setting a session value and checking it in your action filter, simply check HttpContext.Current.Session.IsNewSession to see if a new session was created for the current request. Modifying your action filter, you would end up with something like this:

[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 you want to get fancy and make sure they had a previous session before the new session that was created for this request, you can update the if statement to check if an old session cookie was sent with the request:

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

But since it looks like you are sending them to a login page, this is probably not something you have to worry about here. If you do use this check, note that this code assumes the default "ASP.NET_SessionId" cookie name; this could be changed in your web.config, in which case you would need to either update the IndexOf parameter with the new cookie name or get the cookie name programmatically.

Share:
18,174
LCJ
Author by

LCJ

.Net / C#/ SQL Server Developer Some of my posts listed below -- http://stackoverflow.com/questions/3618380/log4net-does-not-write-the-log-file/14682889#14682889 http://stackoverflow.com/questions/11549943/datetime-field-overflow-with-ibm-data-server-client-v9-7fp5/14215249#14215249 http://stackoverflow.com/questions/12420314/one-wcf-service-two-clients-one-client-does-not-work/12425653#12425653 http://stackoverflow.com/questions/18014392/select-sql-server-database-size/25452709#25452709 http://stackoverflow.com/questions/22589245/difference-between-mvc-5-project-and-web-api-project/25036611#25036611 http://stackoverflow.com/questions/4511346/wsdl-whats-the-difference-between-binding-and-porttype/15408410#15408410 http://stackoverflow.com/questions/7530725/unrecognized-attribute-targetframework-note-that-attribute-names-are-case-sen/18351068#18351068 http://stackoverflow.com/questions/9470013/do-not-use-abstract-base-class-in-design-but-in-modeling-analysis http://stackoverflow.com/questions/11578374/entity-framework-4-0-how-to-see-sql-statements-for-savechanges-method http://stackoverflow.com/questions/14486733/how-to-check-whether-postback-caused-by-a-dynamic-link-button

Updated on June 16, 2022

Comments

  • LCJ
    LCJ almost 2 years

    I have a MVC4 application with Windows Authentication. User can type url of any of the 10 views to load the application. There is no specific home page

    I need to redirect to a session timeout view if the user was idle for more than a minute. I have kept the session timeout value in config file as one minute. And I have created an action filter to check one particular session value. This particular session value is set in the Session_Start of the Global.asax.

    But, when the timeout period is over, the request again hits the Session_Start and it is assigning the value. Hence my action filter is not redirecting to the error view. What are the possible solutions to overcome this?

    Web.Config

    <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>
    

    Action Filter

    [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);
            }
        }
    }
    

    Global.ASAX

    protected void Session_Start(object sender, EventArgs e)
    {
        Session["IsActiveSession"] = DateTime.Now;
    }
    
  • RickNZ
    RickNZ almost 10 years
    Blog post link is broken.
  • markegli
    markegli almost 10 years
    Thanks, I have replaced it.
  • markegli
    markegli over 9 years
    The link for explaining how to check for an old session was not ideal, so I have just moved the explanation inline.