MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Filter我们不得不去单独的Controller或者Action去定义
如图:

那么问题来了,我现在想在FitlerConfig里面去维护所有的过滤器,但是又想实现自定义的过滤器该咋搞,MVC默认不支持!
我们先来看看,MVC默认的Fitlers注册是怎样的
官方源码:GlobalFilterCollection.cs
GlobalFilters.cs
再看看,App_Start里面的FilterConfig.cs
可以发现,其实是GlobalFilters里面定义了静态的GlobalFIlterCollection对象,然后通过FilterConfig像这个静态的集合注册Filters,那么我们没看到MVC哪调用了这个集合,是的,Global里面是没有明确写出来,但是我们来看看FilterProviders.cs的源码
在静态的构造函数中就已经通过Providers.Add(GlobalFilters.Filters);把GlobalFilters.Filters集合给添加进去了,然后MVC每次请求会调用IFilterProvider.GetFilters,那为什么自带的GlobalFilterCollection就不能实现自定义的过滤器呢,请看最上面GlobalFilterCollection.cs的GetFilters代码,他直接返回所有的Filters,而且这个类不能重写,好吧!我们来自己写一个实现自定义过滤器!
可以完全照搬GlobalFilterCollection.cs,GlobalFilters.cs代码,然后根据自己的需求改改
这里我们要通过GetFilters实现自己的筛选规则
看看原始方法源码:
| 1 2 3 4 5 | IEnumerable<Filter> IFilterProvider.GetFilters(ControllerContext controllerContext,            ActionDescriptor actionDescriptor)        {            returnthis;        } | 
这个方法传进来两个参数:ControllerContext和ActionDescriptor
我们添加Add方法
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /// <summary>        /// 注册注册局部规则过滤器        /// </summary>        /// <param name="func"></param>        /// <param name="filter"></param>        /// <param name="order"></param>        publicvoidAdd(Func<ControllerContext, ActionDescriptor, bool> func, objectfilter, intorder)        {            Add(func, filter, order);        }        privatevoidAdd(Func<ControllerContext, ActionDescriptor, bool> func, objectfilter, int? order)        {            ValidateFilterInstance(filter);            items.Add(newFilterItem            {                filter = newFilter(filter, FilterScope.Global, order),                func = func            });        } | 
| 1 | FilterItem是我自己写的一个类,用来存储设置的Filters跟规则的Func | 
| 1 2 3 4 5 | publicclassFilterItem    {        publicFilter filter { get; set; }        publicFunc<ControllerContext, ActionDescriptor, bool> func { get; set; }    } | 
然后改造GetFilters方法
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | publicIEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)        {            foreach(FilterItem item initems)            {                if(item.func == null)                {                    yieldreturnitem.filter;                }                else                {                    boolresult = item.func(controllerContext, actionDescriptor);                    if(result)                        yieldreturnitem.filter;                }            }        } | 
这样在执行GetFilters的时候就会根据注册的所有Filters进行筛选匹配出符合条件的Filters
最后App_Start中自定义FilterConfig注册Filtes
然后在Global添加自定义的Filters注册
FilterProviders.Providers.Add(Geo.Mvc.Provider.GlobalFilters.Filters);
测试:
新建HomeController,写上两个Action分别为Index和Test
| 1 2 3 4 5 6 7 8 9 | publicActionResult Index()        {            returnContent("Index");        }        publicActionResult Test()        {            returnContent("test");        } | 
自己随便写个Filter测试
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | publicclassTestFilter : IActionFilter    {        publicvoidOnActionExecuted(ActionExecutedContext filterContext)        {            filterContext.HttpContext.Response.Write("执行前!<br/>");        }        publicvoidOnActionExecuting(ActionExecutingContext filterContext)        {            filterContext.HttpContext.Response.Write("执行后!<br/>");        }    } | 
去App_Start中自定义的Filter注册
| 1 2 3 4 5 6 7 8 9 10 11 | publicclassMyFilterConfig    {        publicstaticvoidRegistGlobalFilters(Geo.Mvc.Provider.MyFlterCollection filters)        {            //filters.Add(new Filters.TestFilter());            filters.Add((c, a) =>            {                returnstring.Compare(a.ActionName, "test", true) == 0;            }, newFilters.TestFilter());        }    } | 
最后执行Index跟Test方法
结果如下:
这个就是当初我们所希望实现的效果!
不知道怎么放附件,我直接贴我的代码好了!
Global.asax的Application_start中
最后App_Start中的MyFilterConfig.cs
OK!
MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器的更多相关文章
- 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
		MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ... 
- Asp.Net 5使用Area及自定义Area
		Asp.Net Mvc里有一个叫做Area的技术,就是可以把不同逻辑组件的controller, view等放到不同的文件夹里.比如所有管理相关的都放到Admin area里.其实之前我一直对这个功能 ... 
- ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action (转载)
		ASP.NET MVC 一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [ ... 
- vue中自定义指令vue.direvtive,自定义过滤器vue.filter(),vue过渡transition
		自定义指令 默认设置的核心指令( v-model,v-bind,v-for,v-if,v-on等 ),Vue 也允许注册自定义指令.注意,在 Vue2.0 里面,代码复用的主要形式和抽象是组件——然而 ... 
- Django框架(七)—— 模板层:变量、过滤器、标签、自定义标签和过滤器
		目录 模板层:变量.过滤器.标签.自定义标签和过滤器 一.模板层变量 1.语法 2.使用 二.模板层之过滤器 1.语法 2.常用过滤器 3.其他过滤器 三.模板值标签 1.for标签 2.if标签 3 ... 
- Spring MVC 项目搭建 -6- spring security 使用自定义Filter实现验证扩展资源验证,使用数据库进行配置
		Spring MVC 项目搭建 -6- spring security使用自定义Filter实现验证扩展url验证,使用数据库进行配置 实现的主要流程 1.创建一个Filter 继承 Abstract ... 
- MVC自定义路由01-为什么需要自定义路由
		本篇体验自定义路由以及了解为什么需要自定义路由. 准备 □ View Models using System.Collections.Generic; namespace MvcApplicati ... 
- Spring MVC 项目搭建 -4- spring security-添加自定义登录页面
		Spring MVC 项目搭建 -4- spring security-添加自定义登录页面 修改配置文件 <!--spring-sample-security.xml--> <!-- ... 
- asp.net mvc maproute定义可变数量的自定义片断变量
		有时候我们定义了如{controller}/{action}/{id}之类的路由规则,但是后面还可能跟上一堆可能会有可能不会有,但是路由规则是一样的,如{controller}/{action}/{i ... 
随机推荐
- bash构造tmux显示tmux ssh状态
			要求: 于tmux内部链接ssh什么时候, 假设有多个ssh主机. 我们要显示相应的主机ip要显示筛查 实现效果 编辑你的bashrc, 由于我习惯在root下操作, 所以/root/.bashrc. ... 
- VirtualBox创建虚拟电脑、执行Genymotion模拟器报错
			当安装完Genynition关于Android应用的调试模拟器之后,在Genymotion执行的平台virtualBox:VirtualBox创建虚拟电脑.执行Genymotion模拟器报错: 错误卖 ... 
- 玩转Web之JavaScript(一)-----javaScript语法总结(一)  与鼠标操作有关的语法
			click() 对象.click() 使对象被点击. event.clientX 返回最后一次点击鼠标 X 坐标值: event.clientY 返回最后一次点击鼠标 Y 坐标值: event ... 
- 在高德地图应用api,和api展出的标记小的应用程序
			<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ... 
- C# 中使用WebClient 请求 https
			WebClient 请求 启用SSL的站点 时,如果站点的证书是不可信的,请求会被阻止,解决办法如下: 添加以下代码: ServicePointManager.ServerCertificateVal ... 
- 第七章——DMVs和DMFs(3)——用DMV和DMF监控TempDB
			原文:第七章--DMVs和DMFs(3)--用DMV和DMF监控TempDB 前言: 我们都知道TempDB是SQLServer的系统数据库,且SQLServer的日常运作严重依赖这个库.因此,监控T ... 
- 在SQL Server Management Studio中可以运行作业但是用T-SQL运行则失败
			原文:在SQL Server Management Studio中可以运行作业但是用T-SQL运行则失败 问题: 在SQL Server Management Studio中可以运行作业但是用T-SQ ... 
- 【Java】实现一个根据日期判断星座程序的编写
			思路 直接根据月份做索引,然后根据日期边界判断是本月的星座还是上月的. 算法 private static String getAstro(int month, int day) { String[] ... 
- JUnit实战(2) - JUnit核心(使用Suite来组合测试)
			创建Java Project项目:ch02-internals MasterTestSuite.java package com.manning.junitbook.ch02.internals; i ... 
- USACO maze1 BFS
			不写了很长的时间bfs该,很长一段时间的中间失误,当延期一次延伸成功的新节点的节点应该被标记为参观.否则,在某些情况下无限期延长队列. 输入一个小坑爹处理称号,能够进来当字符串被读取.然后用周围的墙上 ... 
