MVC 3 / Jquery AJAX / Session Expires / C# - Handling session timeout durng ajax call

Arcadian picture Arcadian · May 14, 2012 · Viewed 6.9k times · Source

I have an ajax call to MVC which returns a partialview. This is all fine until the session ends or the cookie expires. When I make the ajax call it displays the content inside a div that was meant to be for the partialview. How can I detect that my session has expired during the ajax call and redirect properly to a full screen/page

Answer

Erik Philips picture Erik Philips · May 14, 2012

I would recommend encapsulating all your requests into a wrapper element:

public class JsonResponse<T>
{
    public JsonResponse()
    {
    }

    public JsonResponse(T Data)
    {
        this.Data = Data;
    }

    public T Data { get; set; }
    public bool IsValid { get; set; }
    public string RedirectTo { get; set; }
}

What model you want to send to your client is in Data.

To get the RedirectTo populated, I use a GlobalAuthorize attribute in the Global.Asax and added a handle for HandleUnauthorizedRequests.

public sealed class GlobalAuthorize : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest
      (AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new JsonResult
            {
                Data = new JsonResponse<bool>
                       {
                           IsValid = false,
                           //RedirectTo = FormsAuthentication.LoginUrl
                           RedirectTo = "/"
                       },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    } 

Additionally, I've encapsulated all my Ajax requests into a single function which checks for the RedirectTo.

function global_getJsonResult(Controller, View, data, successCallback, completeCallback, methodType)
{
    if (IsString(Controller)
        && IsString(View)
        && !IsUndefinedOrNull(data))
    {
        var ajaxData;
        var ajaxType;

        if (typeof (data) == "string")
        {
            ajaxData = data;
            ajaxType = "application/x-www-form-urlencoded"
        }
        else
        {
            ajaxData = JSON.stringify(data);
            ajaxType = "application/json; charset=utf-8";
        }
        var method = 'POST';

        if (!IsUndefinedOrNull(methodType)) 
        {
            method = methodType;
        }

        var jqXHR = $.ajax({
            url: '/' + Controller + '/' + View,
            data: ajaxData,
            type: method,
            contentType: ajaxType,
            success: function(jsonResult)
            {
                if (!IsUndefinedOrNull(jsonResult)
                    && jsonResult.hasOwnProperty("RedirectTo")
                    && !IsUndefinedOrNull(jsonResult.RedirectTo)
                    && jsonResult.RedirectTo.length > 0)
                {
                    $.fn.notify('error', 'Login Expired', 'You have been inactive for a prolonged period of time, and have been logged out of the system.');
                    window.setTimeout(function() { window.location = jsonResult.RedirectTo }, 5000);
                }
                else if (IsFunction(successCallback))
                {
                    successCallback(jsonResult, Controller + '/' + View);
                }
            },
            error: function(jqXHR, textStatus, errorThrown)
            {
                if (errorThrown != 'abort')
                {
                    $.fn.notify('error', 'AJAX Connection Error', textStatus + ': ' + errorThrown);
                }

            },
            complete: function(jqXHR, textStatus)
            {
                if (IsFunction(completeCallback))
                {
                    completeCallback(jqXHR, textStatus, Controller + '/' + View);
                }
            }
        });

        return jqXHR;
    }
}