Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Session Handling in ASP.NET MVC 5 for Synchronous/Asynchronous Requests

0.00/5 (No votes)
8 Oct 2014 1  
Session handling for asynchronous requests made from jquery

Introduction

Basic use of session in MVC web applications is as follows:

  1. Check user is logged in or not
  2. To hold authorization information of user logged in
  3. To hold temporary other data
  4. Check session Timeout on user action for each controller

Background

Problem Statement

Using asynchronous (Ajax) request - It is a very common situation to use jquery Ajax or unobtrusive Ajax API of MVC to make asynchronous request in MVC. Both jquery Ajax and unobtrusive Ajax are very powerful to handle asynchronous mechanism. But in most situations, we prefer to use jquery Ajax to have fine tuned control over the application. And now suppose we want to check the session timeout for each asynchronous call in our application. We are using JSON to grab a data on form and send it with asynchronous request. So we dropped in situation where:

  1. Normal redirect won’t work well.
    Example:
    RedirectToAction("LoginView", "LoginController"); // won't work well with Ajax calls 
  2. We need to check session timeout in action method. A repetitive code in each action method hence reduced code reusability and maintainability.
    Example:
    if (session.IsNewSession || Session["LoginUser"] == null) { //redirection logic }

Using the Code

Solution

We can use base controller class or take advantage of action filters of MVC.

  1. Using base controller class and overriding OnActionExecuting method of Controller class:
    public class MyBaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpSessionStateBase session = filterContext.HttpContext.Session;
            if (session.IsNewSession || Session["LoginUser"] == null)
            {
                filterContext.Result = Json("Session Timeout", "text/html");
            }
        }
    }

    And inheriting base class as:

    public class MyController : BaseController
    {
    //action methods…
    }

    Limitation of this approach is that it covers up each action method.

  2. Using action filter attribute class of MVC 5. So we can fine tune each controller action as required.
[AttributeUsage(AttributeTargets.Class | 
    AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class SessionTimeoutFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        // If the browser session or authentication session has expired...
        if (session.IsNewSession || Session["LoginUser"] == null)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                // For AJAX requests, return result as a simple string, 
                // and inform calling JavaScript code that a user should be redirected.
                JsonResult result = Json("SessionTimeout", "text/html");
                filterContext.Result = result;
            }
            else
            {
                // For round-trip requests,
                filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary {
                { "Controller", "Accounts" },
                { "Action", "Login" }
                });
            }
        }
        base.OnActionExecuting(filterContext);
    }
//other methods...
}

Jquery code at client side is as follows:

$.ajax({
    type: "POST",
    url: "controller/action",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: JSON.stringify(data),
    async: true,
    complete: function (xhr, status) {
            if (xhr.responseJSON == CONST_SESSIONTIMEOUT) {
                RedirectToLogin(true);
                return false;
            }
            if (status == 'error' || !xhr.responseText) {
                alert(xhr.statusText);
            }
        }
    });
}    

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here