Tuesday, January 12, 2016

ASP.NET MVC Session Expire Handling

In this section we shall see about, Handling the session expiry globally in ASP.NET MVC applications.

  1. Session expiry handling in server side
  2. Session expiry handling through Javascript

Session expiry handling in server side

  
All the requests/calls to the MVC application points to the particular action in an controller. Session expiry can be controlled through Attributes targeting on Actions and Controllers.

First prepare the session expire attribute class by inheriting System.Web.Mvc.ActionFilterAttribute

    [AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class SessionExpireFilterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            HttpContext ctx = HttpContext.Current;

            // check  sessions here
            if (HttpContext.Current.Session["username"] == null)
            {
                if (new HttpRequestWrapper(ctx.Request).IsAjaxRequest())
                {
                    ctx.Items["SessionExpired"] = true;                   
                    FormsAuthentication.SignOut();
                }
                else
                {
                    //string redirectUrl = string.Format("/Account/Login?returnUrl={0}", ctx.Request.Url.AbsolutePath);
                    filterContext.Result = new RedirectResult(string.Format("/Account/Login?returnUrl={0}", ctx.Request.Url.AbsolutePath));
                    FormsAuthentication.SignOut();
                    return;
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }


Applying the session expire attribute on Controllers and Actions : 


A MVC Controller will have many actions in it. If all actions in the controller needs to be handled with session expiry, the attribute can be applied on the Controller class itself. All the actions in the controller will be handled with session expiry

 [SessionExpireFilterAttribute]
    public class ProfileController : Controller
    {
       
        [Authorize]
        public ActionResult Index()
        {            
            return View();
        }
   }

If particular action(s) in the controller needs to handled with session expiry case, the session expiry attributes can be applied on the required actions only.


    public class AccountController : Controller
    {
        
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
        }

 [SessionExpireFilterAttribute]
        public ActionResult MyDashboard()
        {
              return View();
        }
     }

The above code redirects when an action is requested and session is expired. If the action is called through an AJAX request, it will not redirect to the login action. For handling the session expiry for AJAX calls, please refer below.

Session expiry handling through Javascript

When an action is called through AJAX request, if the session is actually expired it will not to the login action. AJAX calls needs to be handled separately. In the SessionExpireFilterAttribute class, the request type is checked and if it is an ajax request, a context item value is added.

The context item value can be checked in Global.asax Application_EndRequest event and appropriate actions can be taken. Please refer the code below,

   protected void Application_EndRequest(Object sender, EventArgs e)
        {
            if (Context.Items["SessionExpired"] is bool)
            {

                Context.Response.StatusCode = 401;
                Context.Response.End();
            }
        }

And in client side, the StatusCode can be compared and appropriate session expiry redirect actions can be done.

 $.ajax({
        type: postType,
        url: _actionUrl,
        data: objInputs,
    }).done(function (msg) {
        Success(msg);
    }).error(function (arg) {
        if (arg.status == 401) {
           alert('Session Timed Out');
            window.location.href = "Account/Login";
        }
    });

No comments:

Post a Comment