If you are using partial views with many ajax request, there might be a situation in which user session expires and if you will try to submit form asynchronously via ajax Log in page will be displayed in partial view(this will occur if you are using authorize attribute on the method you are calling).
Add this method to global.asax.cs file.
// To use for ajax request when user session expired
In main.js file or script section on your main view(cshtml file if using Razor) add this:
http://api.jquery.com/ajaxComplete/ - More on ajax Complete method
http://stackoverflow.com/questions/3431343/asp-net-mvc-forces-an-ajax-request-be-redirected-to-the-login-page-when-the-form - Inspired by this post
Add this method to global.asax.cs file.
// To use for ajax request when user session expired
protected void Application_EndRequest() { var context = new HttpContextWrapper(Context); // If we're an ajax request, and doing a 302, then we actually need to do a 401 if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest()) { Context.Response.Clear(); Context.Response.StatusCode = 401; } }
In main.js file or script section on your main view(cshtml file if using Razor) add this:
var $document = $(document); handleAjaxError = function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status == 401) { //refresh the page, as we are not longer authorized location.reload(); } };
Since we already lost session, we want to refresh the page and user will be redirect automatically to Log in page, rather than displaying Log in page in small partial view.
$document.ajaxComplete(function(event, XMLHttpRequest, AjaxOptions){ handleAjaxError(XMLHttpRequest); });
http://api.jquery.com/ajaxComplete/ - More on ajax Complete method
http://stackoverflow.com/questions/3431343/asp-net-mvc-forces-an-ajax-request-be-redirected-to-the-login-page-when-the-form - Inspired by this post
This worked for me... but because I don't like magic numbers I refactored it to this:
ReplyDeleteprotected void Application_EndRequest()
{
var context = new HttpContextWrapper(Context);
if (Context.Response.StatusCode == (int)HttpStatusCode.Redirect && context.Request.IsAjaxRequest())
{
Context.Response.Clear();
Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
Thanks!
--SBC
Yes, using enums is of course possible in this case. I just wanted to be consistent with javascript code, plus it is good to know which http status code means as you would get response from most services as an integer.
ReplyDelete