.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:后期再有优化还发在这里,持续关注哦

仅供学习参考,如有侵权联系我删除

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值