溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

.net mvc session失效怎么辦

發(fā)布時間:2021-09-16 15:58:28 來源:億速云 閱讀:92 作者:小新 欄目:開發(fā)技術

這篇文章主要介紹了.net mvc session失效怎么辦,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

最近解決基于.net mvc項目的session失效問題,這個跟大家聊聊。

1.問題分析

.net mvc中,Session失效需要考慮幾種情況:

?基于權限認證的Action,使用非Ajax請求;

?基于權限認證的Action,使用JQueryt Ajax請求;

?基于權限認證的Action,使用.net mvc封裝的Ajax請求;

?無權限認證的Action,使用非Aajx請求;

?無權限認證的Action,使用原生JQuery Ajax請求;

?無權限認證的Action,使用.net mvc封裝的Ajax請求;

基于權限認證的Action,session失效后AuthorizeAttribute都可以攔截,并在HandleUnauthorizedRequest方法中處理;無權限認證的Action需要在自定義的filter中,根據新建Session與已請求Session的區(qū)別進行判斷和處理。

2.基于權限認證的非Ajax請求

Authorize filter優(yōu)先于其他功能過濾器執(zhí)行,因此這里繼承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在系統(tǒng)中存在兩種返回結果:JsonResult和PartialViewResult。

?JsonResult理論上可以通過在返回的結果上增加session超期屬性,客戶端進行判斷即可。但是考慮到項目已經完成,在所有ajax請求上增加判斷邏輯有些繁瑣。

服務端代碼處理ajax請求:

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";
}
}

?PartialViewResult情況的存在,直接否定上面的設想。項目中大部分Ajax請求都是基于.net mvc封裝的,直接更新指定div。

為了不做大量更改、且統(tǒng)一處理兩種返回結果的ajax請求,找到了另外一種方法

jQuery.ajaxSetup()

該函數用于更改jQuery中AJAX請求的默認設置選項。之后執(zhí)行的所有AJAX請求,如果對應的選項參數沒有設置,將使用更改后的默認設置。

因此我們的客戶端代碼可以這樣統(tǒng)一處理:

//解析ajax請求session超時問題
$.ajaxSetup({
complete: function(xmlHttpRequest, textStatus) {
var sessionStatus = xmlHttpRequest.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
}
});

本以為到這里就萬事大吉啦,結果一不小心又發(fā)現一個問題,基于.net mvc的jquery.unobtrusive-ajax封裝的ajax請求調用,沒有達到攔截處理的效果。經過反復調試無果,最終還是注意到上面那段話

jQuery.ajaxSetup()該函數用于更改jQuery中AJAX請求的默認設置選項。之后執(zhí)行的所有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失效問題基本解決,存在兩個瑕疵:

?修改了jquery.unobtrusive-ajax的源碼,總感覺心里別扭;

?任何注冊了compelete事件的ajax請求,都需要自己處理session問題。

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失效,結果發(fā)現項目現有框架總會莫名奇妙的在登錄后的第一個業(yè)務請請求時把session超期時間改為60分鐘,沒有找到為什么。后來只能通過在同一個瀏覽器打開兩個tab頁,登錄系統(tǒng)后,在一個tab頁推出的方法模擬。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“.net mvc session失效怎么辦”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI