最近在研究有关.net mvc项目中的session失效问题,下面小编把研究过程给大家共享下,大家可以参考下。
最近解决基于.net mvc项目的session失效问题,这个跟大家聊聊。
1.问题分析
.net mvc中,Session失效需要考虑几种情况:
"background-color: #ffff00">2.基于权限认证的非Ajax请求
Authorize filter优先于其他功能过滤器执行,因此这里继承AuthorizeAttribue,在HandleUnauthorizedRequest中处理session请求。
public class AuthorizeOfHandleUnAuthorizeAttribute:AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { //session失效重定向到登录页面 filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { Controller = "Login", Action = "Login" })); } }
3.基于权限认证的Ajax请求
Ajax请求的Action在系统中存在两种返回结果:JsonResult和PartialViewResult。
"htmlcode">
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { //ajax请求session超期处理 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" })); }
客户端代码(这种处理方式对于返回结果为PartialViewResult的Action是不适用的):
onSuccess: function (xhr, status) { //获取响应头,sessionstatus, var sessionstatus = xhr.getResponseHeader("sessionstatus"); if (sessionstatus == "timeout") { window.location = "/Login/Login"; } }
"htmlcode">
//解析ajax请求session超时问题 $.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"), ["data", "status", "xhr"]).apply(element, arguments); }, error: function () { getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(element, arguments); } });
我们看到jquery.unobtrusive-ajax注册了ajax请求的compelete事件,因此我们写的默认处理程序就被覆盖啦。实在没想到什么好办法,只好改下jquery.unobtrusive-ajax的源码了:
complete: function (xhr,status) { loading.hide(duration); //解析ajax请求session超时问题 var sessionStatus = xhr.getResponseHeader("sessionstatus"); if (sessionStatus === "timeout") { window.location = "/Login/Login"; } getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments); },
至此,基于认证的ajax请求session失效问题基本解决,存在两个瑕疵:
"background-color: #ffff00">4.无权限任务的Action
无权限认证的Action的Session失效问题,处理代码如下:
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" })); } } }
无权限认证的Action的Ajax可以仿照上面有权限认证的处理方法处理,这里就不再粘代码啦。个人感觉,无权限认证的Action请求,大多可以不用考虑session失效情况,因为这些Action大多不从session里获取信息,只是做公共信息的查询。
5.遗留问题
至此问题基本解决,但是过程中遇到了一个莫名其妙的问题,暂且记下:
我原本通过在配置文件把session超期时间设置的很小来模拟session失效,结果发现项目现有框架总会莫名奇妙的在登录后的第一个业务请请求时把session超期时间改为60分钟,没有找到为什么。后来只能通过在同一个浏览器打开两个tab页,登录系统后,在一个tab页推出的方法模拟。
以上所述是小编给大家介绍的.net mvc session失效问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!