Global "ajax call" notification with asp.net mvc / jquery
I need to be notified anytime a large asp.net mvc web application makes an ajax call to the server. We use both jquery and built-in Ajax methods. * To make remote calls, and I would like a global way to know when we are making a call, without having to manually enter any "IsMakingCall" method for each request.
The root problem we are trying to solve is session timeout. If the user leaves the page up and goes to lunch (for example) they get errors when they return because the ajax call returns the login page, not the expected json result or partial html.
My idea was to have a js timer that will be reset on every ajax call. That way, if the timer runs out (i.e., their session is already disconnected), I can just automatically log them out. This is how sites like Bank of America and mint.com work.
Thanks!
a source to share
I handle the problem you describe differently on the client side. I have a jQuery plugin on my home page that will force the user to resume their session via a dialog before it expires. If the user is unresponsive (or logged out), it invokes the application logout action. If the user "refreshes" their session, they return the AJAX server to the server, resetting the server-side sliding window.
You can find code on my blog , http://farm-fresh-code.blogspot.com . It does not currently account for AJAX actions that can resume the session, but you can use it so that jQuery AJAX through the global ajaxStart will reset the timer. It uses ajaxStart to reset the timer when making a jQuery AJAX request. I am not using MS AJAX, so I am not sure if there is a global hook you can use. This doesn't sound like a code check, but you can manually add one via AjaxOptions to each request. You can also explore adding a handler to the Sys.Net.WebRequestManager.
a source to share
Basically, the problem here is in the default behavior of returning the login page. The result of this is 200 OK
, which for jQuery is a successful call. Fix this handling for ajax calls from MVC and you should be good.
I think the easiest way to deal with this is to change the way authorization works for ajax scripts. You can specify if the request is an Ajax at this point and return a similar status code that ASP.NET does not trigger name redirects for (403). Then jQuery will be interpreted as a failure and end up in that code on the client script.
Then you can easily use a shared function in a shared js file to handle a friendly way to tell the user that they have expired during the session.
Something like this can do it
public class AjaxAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new ContentResult();
filterContext.HttpContext.Response.StatusCode = 403; // 401 would make ASP.NET return the login page and a 200 OK status
}
else
base.HandleUnauthorizedRequest(filterContext);
}
}
a source to share