English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Detailed Explanation of .net mvc Session Expiration Issue

I have recently been studying the session expiration issue in .NET MVC projects, and below I will share the research process with everyone, which can be referred to.

I recently resolved the session expiration issue in a .NET MVC project and would like to discuss it with everyone.

1Problem Analysis

In .NET MVC, there are several situations to consider when the session expires:

• Actions based on permission authentication use non-Ajax requests;

• Actions based on permission authentication use JQuery Ajax requests;

• Actions based on permission authentication use .NET MVC encapsulated Ajax requests;

• Actions without permission authentication use non-Ajax requests;

• Actions without permission authentication use native JQuery Ajax requests;

• Actions without permission authentication use .NET MVC encapsulated Ajax requests;

Actions based on permission authentication can be intercepted by AuthorizeAttribute after session expiration and are processed in the HandleUnauthorizedRequest method; Actions without permission authentication need to be judged and processed in a custom filter based on the difference between a newly created session and the requested session.

2Non-Ajax request based on permission authentication

The Authorize filter is executed before other functional filters, therefore it inherits AuthorizeAttribute and handles session requests in HandleUnauthorizedRequest.

public class AuthorizeOfHandleUnAuthorizeAttribute:AuthorizeAttribute
{}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{}
//Session expiration redirects to the login page
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}
}

3.Based on permission authentication of AJAX requests

The Action of AJAX requests in the system has two types of return results: JsonResult and PartialViewResult.

•Theoretically, JsonResult can be used to add a session timeout attribute to the returned results, and the client can make a judgment. However, considering that the project is already completed, adding judgment logic to all AJAX requests is somewhat cumbersome.

Server code handling AJAX requests:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{}
//Handling session timeout for AJAX requests
if (filterContext.HttpContext.Request.IsAjaxRequest())
{}
filterContext.HttpContext.Response.AppendHeader("sessionstatus","timeout");
filterContext.HttpContext.Response.End();
return;
}
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}

Client code (this handling method is not applicable to actions that return PartialViewResult):

onSuccess: function (xhr, status) {
//Get the response header, sessionstatus,
var sessionstatus = xhr.getResponseHeader("sessionstatus");
if (sessionstatus == "timeout") {
window.location = "/Login/Login";
}
}

•The existence of PartialViewResult directly negates the above assumption. Most Ajax requests in the project are based on .net mvc encapsulation, and the specified div is updated directly.

To avoid making a lot of changes and to uniformly handle AJAX requests with two types of return results, another method was found.

jQuery.ajaxSetup()

This function is used to change the default setting options of AJAX requests in jQuery. All AJAX requests executed after this will use the changed default settings if the corresponding option parameters are not set.

Therefore, our client code can be handled uniformly as follows:

//Parsing the session timeout issue of AJAX requests
$.ajaxSetup({
complete: function(xmlHttpRequest, textStatus) {
var sessionStatus = xmlHttpRequest.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
}
});

本以为到这里就万事大吉啦,结果一不小心又发现一个问题,基于.net mvc的jquery.unobtrusive-ajax封装的ajax请求调用,没有达到拦截处理的效果。经过反复调试无果,最终还是注意到上面那段话

jQuery.ajaxSetup()该函数用于更改jQuery中AJAX请求的默认设置选项。之后执行的所有AJAX请求,如果对应的选项参数没有设置,将使用更改后的默认设置。

这里说的比较明白了,那肯定就是jquery.unobtrusive-ajax封装的时候捣的鬼啦,翻开源码一看果然如此:

$.extend(options, {
type: element.getAttribute("data-ajax-method") || undefined,
url: element.getAttribute("data-ajax-url") || undefined,
cache: !!element.getAttribute("data-ajax-cache"),
beforeSend: function (xhr) {
var result;
asyncOnBeforeSend(xhr, method);
result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(element, arguments);
if (result !== false) {
loading.show(duration);
}
return result;
},
complete: function (xhr, status) {
loading.hide(duration);
getFunction(element.getAttribute("data-ajax-complete": ["xhr", "status"],).apply(element, arguments);
},
success: function (data, status, xhr) {
asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
getFunction(element.getAttribute("data-ajax-success\
},
error: function () {}}
getFunction(element.getAttribute("data-ajax-failure": ["xhr", "status", "error"],).apply(element, arguments);
}
});

We see that jquery.unobtrusive-AJAX has registered the compelete event for AJAX requests, so the default handler we wrote has been overridden. I really can't think of a good way, so I have to modify jquery.unobtrusive-The source code of AJAX:

complete: function (xhr, status) {
loading.hide(duration);
//Parsing the session timeout issue of AJAX requests
var sessionStatus = xhr.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
getFunction(element.getAttribute("data-ajax-complete": ["xhr", "status"],).apply(element, arguments);
},

So far, the session expiration issue of authenticated AJAX requests has been basically resolved, but there are two flaws:

•Modified by jquery.unobtrusive-The source code of AJAX always feels uncomfortable in my heart;

•Any AJAX requests registered with the compelete event need to handle the session issue themselves.

4.Action without permission tasks

There is a session expiration issue with the Action that does not have permission authentication, the handling code is as follows:

if (filterContext.HttpContext.Session != null)
{}
if (filterContext.HttpContext.Session.IsNewSession)
{}
var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];
if (sessionCookie != null && sessionCookie.IndexOf("ASP_NET_SessionId", StringComparison.OrdinalIgnoreCase) >= 0)
{}
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}
}
}

Ajax for actions without permission authentication can be processed according to the method with permission authentication above, and there is no need to paste the code here. Personally, it is generally not necessary to consider session timeout for action requests without permission authentication, because these actions mostly do not obtain information from the session, but only perform public information queries.

5. Leftover issues

So far, the problem has been basically solved, but encountered a strange problem during the process, let's note it down for the time being:

I originally simulated session timeout by setting the session timeout time very small in the configuration file, but found that the existing framework of the project would change the session timeout time to something strange at the first business request after logging in.60 minutes, couldn't find out why. Later, it could only be simulated by opening two tabs in the same browser, logging in to the system, and simulating the method in one tab.

The above is the .net mvc session timeout problem introduced by the editor to everyone, hoping it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Thank you very much for everyone's support for the Yell Tutorial website!

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You May Also Like