首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET MVC 过滤器

ASP.NET MVC 过滤器

作者头像
李郑
发布2019-12-11 18:11:10
1.9K0
发布2019-12-11 18:11:10
举报
文章被收录于专栏:漫漫全栈路漫漫全栈路

过滤器是 ASP.NET MVC 中很重要的一个功能,过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户。

简述过滤器

过滤器理论上有以下功能:

  • 判断登录与否或用户权限
  • 决策输出缓存
  • 防盗链
  • 防蜘蛛
  • 本地化与国际化设置
  • 实现动态Action(做权限管理系统的好东西)

实现过滤器的两种方法:

  • 自定义类继承自相应的类或借口,重写方法,作为特性使用
  • 在控制器类中重写方法 特性方法的使用:
    • 作为Controller或Action的特性
    • 在Global中注册为全局过滤器,应用于所有的Controller的Action

    注意:如果继承自接口,则需要让类实现FilterAttribute,才能作为特性使用。参数类均继承自ControllerContext,主要包含属性请求上下文,路由数据,结果。

过滤器的四种实现

四种常用的过滤器: 过滤器类型 | 接口 | 默认实现 | 描述 :–:|:–:|:–:|:–: Authorization | IAuthorization | AuthorizeAttribute | 首先运行,在其他过滤器的操作方法 Action | IActionFilter | ActionFilterAttribute | 运行之前和之后的动作方法 Result | IResultFilter | ActionFilterAttribute | 运行前后执行的操作结果 Exception | IExceptionFilter | HandleErrorAttribute | 如果只运行一个过滤器,操作方法或行动结果抛出一个异常

MVC5 中新增了 Authentication 过滤器,用于验证。在 MVC5 中,将原本的 Authorization 拆分为 Authentication(身份验证)和 Authorization(授权)两个,MVC 接受到 Web 页面请求时,首先将执行所有的 Authentication 过滤器,如果请求需要认证且已经被验证过了,就会继续下一步处理,若没有通过身份验证,则会停止处理。

下面先说下身份过滤验证器,然后以身份过滤验证器为例介绍几种实现过滤器的方法,再介绍后续的其他的过滤器!

身份验证过滤器

定义身份验证的过滤器,需要在约束的Action执行前来执行,重写OnAuthorization方法。

通过一个简单的实例,来展示Filter的模式:

创建过滤器

现在项目中添加一个 Filter 文件夹来存储过滤器,然后来写第一个 Filter 示例 - MyAuthorization.cs

using System.Web.Mvc;

namespace STU_mvc.Areas.UserManage.Filters
{
    public class MyAuthorization: AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //.net framework 默认身份验证
            //base.OnAuthorization(filterContext); 

            //跳转页面,使用Result,而不是使用Response.Redirect() 因为它会继续执行Action
            //filterContext.Result = new RedirectResult(UrlHelper.GenerateUrl("","","","","","",true));

            //获取路由数据,当前上下文匹配到路由规则后,得到的一个对象
            //filterContext.RouteData 

            //获取上下文
            filterContext.HttpContext.Response.Write("Test");
        }
    }
}

注意: 这是一个身份验证的 Filter ,因此这个类必须继承自System.Web.Mvc 中的 AuthorizeAttribute ,并对OnAuthorization()方法进行重写。

特性模式调用控制器

写好了 Filter 还得去调用他,调用 Filter 的方法就是,在 Action 前为其申明一个特性

using STU_mvc.Areas.UserManage.Filters;
using System.Web.Mvc;
namespace STU_mvc.Areas.UserManage.Controllers
{
    public class HomeController : Controller
    {
        // GET: UserManage/Home
        [MyAuthorization]
        public ActionResult Index()
        {
            return View();
        }
    }
}

如上代码中的控制器直接返回了一个 Test ,编译-运行-访问当前路由,会发现浏览器在 html 代码前直接附加了一个 Test ,由此可知,过滤器发生在 Action 之前。

直接返回上下文
直接返回上下文

注意:Filter 是作为特性而附加给 Action 的,因此可以被不同的 Action 重复调用,且只在调用后才会执行。同样,如果一个 Controller 中的所有 Action 都需要使用这个 Filter ,则可以直接给当前 Controller 类附加上这个 Filter 特性即可。

其他的过滤器调用方法

全局过滤器

Global.asxs 中 FilterConfig 调用了 App_Start 中的 FilterConfig.cs 文件,这个文件在全局中申明了过滤器,及所有在此处注册的过滤器,会被所有 Controller 的 所有 Action 执行。

public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //filters.Add(new HandleErrorAttribute());

            //在全局中注册过滤器,则所有控制器的所有行为都会执行
            filters.Add(new MyAuthorization());
        }
    }

RegisterGlobalFilters() 方法的形参表面,filters 是一个集合,因此只需要在其中使用 filters 的 Add 方法申明过滤器即可。

重写方法实现过滤

针对某一控制器进行重写,应用范围为当前控制器下的所有的行为。

在控制器中 输入 override OnAuthentication 自动补全,为当前控制器重写该方法:

protected override void OnAuthentication(AuthenticationContext filterContext)
{
    filterContext.HttpContext.Response.Write("test for controller");
}

重写完成后,调试可以发现, 被重写OnAuthenticationhome 控制器执行了 filter 的内容,而未被重写的test 控制器则不受影响。

同样的,也可以添加一个继承自Controller 的基类,并重写基类的OnAuthentication ,之后让控制器不再继承Controller,而是间接继承基类。 即: HomeController -> BaseController -> Controller ,通过为 BaseController 重写 filter 来实现过滤器。

异常处理过滤器

异常处理过滤器,用于当发生异常时,进行自定义异步处理,记录日志,跳转页面等。

创建过滤器

首先创建过滤器 MyException.cs,同样的,在 Filter 文件夹下新建一个类,继承自 HandleErrorAttribute

注意:OnException 的 base 特性不能删除,否则捕获不到异常

namespace STU_mvc.Areas.UserManage.Filters
{
    public class MyExcepition: HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            //OnException 的 base 特性不能删除,否则捕获不到异常
            base.OnException(filterContext);

            //记录日志

            //直接跳转到异常处理页面
            filterContext.Result= new RedirectResult("/Error/400.html");
        }
    }
}

全局注册异常过滤器

然后使用全局注册,通常来说,异常处理都是全局有效的:

注意:如果要实现自定义

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //系统默认的异常处理过滤器
        //filters.Add(new HandleErrorAttribute());

        //在全局中注册过滤器,则所有控制器的所有行为都会执行
        //filters.Add(new MyAuthorization());

        //添加自己的异常处理过滤器
        filters.Add(new MyExcepition());
    }
}

配置启动自定义异常处理

注意: 要使用自定义的异常处理,需要在 web.config中为 system.web添加<customErrors mode ="on" /> 节点,开启自定义异常。

<system.web>
    <customErrors mode ="On" defaultRedirect="Error/400.html"/>
    ……
exception
exception

配置完成后,我们随便输入一个不匹配的路由,就会返回到我们提前编写好的400页面,并通过 url 暴露出异常的路由信息,而正常的路由请求则不受此影响。

##行为过滤器

Action 过滤器继承ActionFilterAttribute实现,并提供了在两个不同时间点执行代码的能力,分别在 行为执行前(OnActionExecuting)/行为执行后(OnActionExecuted) 执行相关操作。

创建过滤器

Filter 目录下新建一个类MyAction,并继承ActionFilterAttribute

public class MyAction: ActionFilterAttribute
{
	//行为执行前
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		filterContext.HttpContext.Response.Write("This line is Before Action execute!");
		//base.OnActionExecuting(filterContext);
	}

	//行为执行后,结果输出前
	public override void OnActionExecuted(ActionExecutedContext filterContext)
	{
		filterContext.HttpContext.Response.Write("This line is After Action execute!");
		//base.OnActionExecuted(filterContext);
	}
}

添加特性

同样的,添加特性使其生效

public class HomeController : Controller
{
	// GET: UserManage/Home
	[MyAction]
	public ActionResult Index()
	{
		Response.Write("Action Execut");
		return View();
	}
}

效果如下:

action
action

return 的 view() 是在 Action 完成后执行的,所以会先显示两个 filter 的结果,再返回 view(),而 Action 中的内容则在二者之间显示。

结果过滤器

同样继承自ActionFilterAttribute实现,并提供了在两个不同时间点执行代码的能力,分别在 结果执行前(On ResultExecuting)/结果执行后(OnResultExecuted) 执行相关操作。

创建结果过滤器

首先创建过滤器 MyResult.cs,同样的,在 Filter 文件夹下新建一个类,继承自 ActionFilterAttribute

public class MyResult: ActionFilterAttribute
{
    //结果执行前执行
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("Before Result<bt />");
    }
    
    //结果执行后执行
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("After Result<bt />");
    }
}

添加特性

同样的,添加特性使其生效

public class HomeController : Controller
{
	// GET: UserManage/Home
	[MyResult]
	public ActionResult Index()
	{
		Response.Write("Action Execut");
		return View();
	}
}

效果如下:

result
result
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述过滤器
  • 过滤器的四种实现
    • 身份验证过滤器
      • 创建过滤器
      • 特性模式调用控制器
    • 其他的过滤器调用方法
      • 全局过滤器
      • 重写方法实现过滤
    • 异常处理过滤器
      • 创建过滤器
      • 全局注册异常过滤器
      • 配置启动自定义异常处理
      • 创建过滤器
      • 添加特性
    • 结果过滤器
      • 创建结果过滤器
      • 添加特性
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档