.Net Core MVC重寫OnActionExecuting方法實現過濾器功能

.Net Core MVC重寫OnActionExecuting方法實現過濾器功能

需求
登錄校驗
實現方式
通過重寫OnActionExecuting方法,實現過濾器
原理
我們知道每個Controller/Action 請求都會觸發OnActionExecuting方法,那麼我們重寫此方法,並判斷當前User是否登錄(筆者通過Cookie方式驗證,見上一篇博客)如果登錄信息存在Cookie那麼讓他可以訪問頁面,如果沒登錄或者登錄過期,重定向到登錄頁
具體實現Code
1.定義一個BaseController

public class BaseController : Controller
{
	//複寫父類的該方法。執行控制器中的方法之前先執行該方法。從而實現過濾的功能。
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		//string _controllerName = filterContext.RouteData.Values["controller"].ToString();
		//string _actionName = filterContext.RouteData.Values["action"].ToString();
		//object _routeName = filterContext.RouteData.DataTokens["area"];
		base.OnActionExecuting(filterContext);  //調用父類的該方法。
		if (Request.Cookies["CurrentUser"] != null)
		{
			//filterContext.HttpContext.Response.Redirect("/QRCodeRecruitment/Index");  //這種跳轉方式,會繼續向下執行Controller的方法並返回ActionResult。
		}
		else
		{
			//這種跳轉方式直接返回一個ActionResult,不會繼續向下執行,而是直接跳轉。速度快。
			filterContext.Result = Redirect("/Login/index"); ///ManageUATClient
		}
	}
}

2.繼承BaseController

public class QRCodeRecruitmentController : BaseController
{
	public IActionResult Index()
	{
		RecruitModel model = new RecruitModel();
		///具體請求代碼...
		return View(model);
	}
}

這樣當直接訪問/QRCodeRecruitment/Index會被OnActionExecuting攔截,通過Debug可以看見斷點會先進入OnActionExecuting,至於方法裏的判斷Request.Cookies["CurrentUser"] != null則是在用戶通過登錄加入到Cookie裏的了,如果沒登陸過直接跳登錄頁filterContext.Result = Redirect("/Login/index");

PS:筆者研究了一晚上,研究出來的一種適用於.Net Core的攔截器方式,至於.Net Core自身帶的那種登錄驗證筆者也試過了。就是用起來比較繁瑣,得先熟悉他本身的那套套路,最不能接受是EF,由於常年維護帶EF的項目,每次改表結構都非常難受,因此筆者不建議EF的,況且EF使用了大量的反射機制,會使查詢速度變慢。當然創建時候是很爽,維護起來可糟心了。

就寫這麼多了,覺得有用點贊評論,大家一起交流

針對ajax/bootstrapTable異步請求不跳頁的補充

補充背景

本以爲就這樣結束了,問題很快暴露出來,那就是Ajax請求訪問數據時,Cookie到期情況,跳頁不成功,Ajax本身就是不刷新頁面的嘛,到攔截器裏面即使filterContext.Result = Redirect("/Login/index");放這個招也不好用,URL是不會變的。那也就意味着,用戶登錄過期以後,點擊什麼也請求不到,還沒反應,我們希望的是重定向到登錄頁。

解決思路

我們在攔截器(過濾器)裏判斷當前請求到底是URL還是異步請求,當時用戶輸入地址的URL請求時,正常走原來的邏輯跳頁,當是Ajax異步請求時,給返回狀態碼,到Ajax請求的返回結果去重定向,問題可解。

具體Code實現

public class BaseController : Controller
{
	public static string childSite = "";
	//複寫父類的該方法。執行控制器中的方法之前先執行該方法。從而實現過濾的功能。
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		if (ConfigurationManager.AppSettings["environment"] == "Prod")
		{
			childSite = "/ManageUATClient";
		}
		base.OnActionExecuting(filterContext);  //調用父類的該方法。
		if (Request.Cookies["CurrentUser"] != null)
		{
			
		}
		else
		{
			//是否爲Ajax請求,Ajax需要返回碼,Ajax請求不能直接跳轉
			if (filterContext.HttpContext.Request.Headers.ContainsKey("x-requested-with"))
			{
				if(filterContext.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest")
				{
					filterContext.Result = new ContentResult() { Content = "CookieTimeOut", StatusCode = 499 };
				}
			}
			else
			{
				filterContext.Result = Redirect(childSite + "/Login/index");
			}
		}
	}
}

前臺Ajax處理代碼

$.ajax({
	url: ...
	type: "POST",
	dataType: "json",
	data: { ... },
	success: function (result) {
		///..
	},
	error: function (e) {
		if (e.status = 499) {
			window.location.href = "/Login/Index";
		}
		console.log(e.status);
		console.log(e.responseText);
	}
});

bootstrapTable處理代碼

onLoadError: function (status, jqXHR) {
	if (status = 499) {
		window.location.href = "/Login/Index";
	}
	console.log(status);
	console.log(jqXHR.responseText);
},

這樣即使登錄過期了,用戶點了什麼東西請求數據就會跳到登錄頁。

**

針對ActionFilterAttribute實現單個或者整個Controller攔截器(過濾器)的補充(2020/06/11 v3.0)

**
上述BaseController : Controller這種寫法是整個繼承了BaseController的所有Action都被攔截,那麼如果希望只攔截某個Action的時候怎麼實現呢?本次補充單個Action的攔截實現。

依然是重寫OnActionExecuting方法

public class WxOauthAttribute : ActionFilterAttribute
{
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		//code etc...
	}
}

注意這裏的WxOauthAttribute類,這個類名前綴WxOauth關鍵字放在Action頭上[WxOauth]即可起到單個Action攔截的作用,即

[WxOauth]
public ActionResult Index(string str)
{
	return View();
}

放在Controller頭上會不會攔截所有Action呢?感興趣可以試試

[WxOauth]
public class ClientController : Controller
{
	//...
}

此寫法只在.NET Framework MVC嘗試過,.NET Core沒試過暫時先補充進來

PS:後期再有優化還發在這裏,持續關注哦

僅供學習參考,如有侵權聯繫我刪除

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章