MVC中的过滤器
authour: | chenboyi |
updatetime: | 2015-05-09 09:30:30 |
friendly link: |
目录:
程序员可以自己定义过滤器,并将其设为全局或者单个类、单个方法上得过滤器,如果要把自定义过滤器设为全局过滤器要做如下操作
下面示例是Global.asax.cs文件和AppStart文件夹下的FilterConfig.cs中的演示
1 public class MvcApplication : System.Web.HttpApplication //Global.asax.cs 2 { 3 /// <summary> 4 /// 注意点,MVC自动生成的执行代码顺序不能改变 5 /// </summary> 6 protected void Application_Start() 7 { 8 //1.0 负责注册当前MVC网站中所有的区域路由规则 9 AreaRegistration.RegisterAllAreas(); 10 11 WebApiConfig.Register(GlobalConfiguration.Configuration); 12 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 13 14 //3.0 注册网站路由规则 15 RouteConfig.RegisterRoutes(RouteTable.Routes); 16 17 BundleConfig.RegisterBundles(BundleTable.Bundles); 18 } 19 }
1 public static void RegisterGlobalFilters(GlobalFilterCollection filters) //FilterConfig.cs 2 { 3 filters.Add(new HandleErrorAttribute()); 4 5 //将自定义类ActionFilterCust 注册成了全局过滤器(截获此网站中所有action的执行,AOP:面向切面编程) 6 filters.Add(new ActionFilterCust()); 7 filters.Add(new AutFiltersAttribute()); 8 filters.Add(new ExceptionFiltersAttribute()); 9 }
4.1 action过滤器 (方法过滤器) 和result过滤器 (结果过滤器) (频繁使用)
应用:一般用于【统一登录验证】和【权限验证】 一般写在OnActionExecuting()方法中
作用:类A必须要继成ActionFilterAttribute,并且重写里面的OnActionExecuting()在action()方法的逻辑执行之前会先执行OnActionExecuting()中的逻辑和OnActionExecuted在action()方法的逻辑执行之后会执行OnActionExecuted()中的逻辑
4.2 action过滤器用法步骤:
4.2.1、自己定义一个继承了类ActionFilterAttribute的自定类名字叫做ActionFilterAttribute1
4.2.2、在App_Start/FilterConfig.cs文件中的public static void RegisterGlobalFilters(GlobalFilterCollection filters) 方法中
添加自定义过滤器的注册代码: filters.Add(new ActionFilterAttribute1());
4.2.3、自定义过滤器如果没有在FilterConfig.cs中进行全局注册,则可以在某个action方法上添加特性标签
例如
[MVCFilter.Filters.ActionFilterAttribute1]
public ActionResult Index()
{
Response.Write("这是Index()方法中输出的文本<br />");
return View();
}
4.2.4、如果想在控制器Home中的所有方法都能够被自定义过滤器切入,就在Home类上面添上自定义标签即可。
4.3 代码演示:
下面是自定义Action过滤器的代码演示:
1 自己定义一个过滤器的写法: 2 /// <summary> 3 /// 方法过滤器 4 /// 作用:是在当前网站中任何控制器的方法执行前,后,返回结果前,后被触发(AOP 面向切面编程) 5 /// </summary> 6 public class ActionFilter1 : ActionFilterAttribute 7 { 8 /// <summary> 9 /// 方法在执行器逻辑代码之前被触发 10 /// </summary> 11 /// <param name="filterContext"></param> 12 public override void OnActionExecuting(ActionExecutingContext filterContext) 13 { 14 //获取当前触发OnActionExecuting()的源action名称是什么 15 string actionName = filterContext.ActionDescriptor.ActionName; 16 17 //获取当前action方法所在的控制器方法 18 string contrlName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 19 20 //获取当前action方法上所有的特性标签,以数组的形式返回 21 var atts = filterContext.ActionDescriptor.GetCustomAttributes(false); 22 23 //获取当前action方法所在控制器的所有特性标签,以数组的形式返回 24 var contrlAtts = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(false); 25 26 //获取当前请求的上下文对象等价于HttpContext.Current 27 //filterContext.HttpContext 28 29 var prmsdic = filterContext.ActionParameters; 30 31 #region 1.0 获取action参数写入日志文件 32 //获取所有的参数:id=100 33 System.Text.StringBuilder prmstxt = new System.Text.StringBuilder(100); 34 foreach (var key in prmsdic.Keys) 35 { 36 prmstxt.AppendFormat("{0}={1} ,", key, prmsdic[key]); 37 } 38 //最后将参数写入日志文件 39 //1.0 写日志文件使用 LogNet4开源的日志文件类库 40 //2.0 使用公司自己开发出来的日志文件类库 41 System.IO.File.AppendAllText(filterContext.HttpContext.Server.MapPath("/log.txt"), prmstxt.ToString()); 42 #endregion 43 44 var tokens = filterContext.RouteData.DataTokens; 45 46 HttpContext.Current.Response.Write("OnActionExecuting---方法在执行器逻辑代码之前被触发----执行之前<br />"); 47 base.OnActionExecuting(filterContext); 48 } 49 50 /// <summary> 51 /// 方法在执行器逻辑代码以后被触发 52 /// </summary> 53 /// <param name="filterContext"></param> 54 public override void OnActionExecuted(ActionExecutedContext filterContext) 55 { 56 HttpContext.Current.Response.Write("OnActionExecuted方法在执行器逻辑代码之前被触发----执行以后<br />"); 57 base.OnActionExecuted(filterContext); 58 } 59 60 /// <summary> 61 /// 方法在将结果返回之前被触发 62 /// </summary> 63 /// <param name="filterContext"></param> 64 public override void OnResultExecuting(ResultExecutingContext filterContext) 65 { 66 HttpContext.Current.Response.Write("OnResultExecuting方法在执行器逻辑代码之前被触发----结果返回前<br />"); 67 base.OnResultExecuting(filterContext); 68 } 69 70 /// <summary> 71 /// 方法在将结果返回之后被触发 72 /// </summary> 73 /// <param name="filterContext"></param> 74 public override void OnResultExecuted(ResultExecutedContext filterContext) 75 { 76 HttpContext.Current.Response.Write("OnResultExecuted方法在执行器逻辑代码之前被触发----结果返回后<br />"); 77 base.OnResultExecuted(filterContext); 78 }
验证过滤器(用来配合实现form(表单)登录验证的)
5.1 特点:在action过滤器运行前执行
5.2 注意:在重写的过程中如果执行了base.OnAuthorization(filterContext); 则会跳转到登录页面
解决方法有两个:
1、在action上贴上[AllowAnonymous] 特性标签
2、在过滤器重写的OnAuthorization方法中不调用base.OnAuthorization(filterContext);
例如:
1 自己定义一个过滤器的写法: 2 /// <summary> 3 /// 在其他过滤器执行之前会被触发 4 /// </summary> 5 public class AuthFilter : AuthorizeAttribute 6 { 7 public override void OnAuthorization(AuthorizationContext filterContext) 8 { 9 filterContext.HttpContext.Response.Write("----这是OnAuthorization--输出的<br />"); 10 //base.OnAuthorization(filterContext); 11 } 12 }
6,HandleErrorAttribute:
6.1 作用:可以统一捕获MVC网站中没有进行try{}catch{}处理的异常
6.2 代码示例:
1 自定义异常过滤器的写法样例: 2 /// <summary> 3 /// 异常过滤器 4 /// </summary> 5 public class Exp : HandleErrorAttribute 6 { 7 public override void OnException(ExceptionContext filterContext) 8 { 9 //base.OnException(filterContext); 10 //统一捕获当前网站中所有action中出现的异常信息 11 Exception exp = filterContext.Exception; 12 string errmsg = exp.ToString(); 13 14 //2.0 将errmsg 存入日志文件或者数据库 15 //yyyy-mm-dd hh:mm:ss 日志类型(普通日志(info),警告信息(Waring),异常信息(Error)) 日志的详细堆栈信息 16 System.IO.File.AppendAllText(filterContext.HttpContext.Server.MapPath("/errorlog.txt"), errmsg + "\r\n"); 17 18 //3.0 告诉mvc框架,当前异常信息已经被程序员处理了,mvc就不需要再将异常信息抛出给用户 19 filterContext.ExceptionHandled = true; 20 } 21 }
7.1 统一跳转到error.cshtml 的系统配置:
如果实现了全局异常过滤器HandleErrorAttribute
a) 请将 filterContext.ExceptionHandled 设置成 false 写法: filterContext.ExceptionHandled = false;
b)在mvc网站的跟目录下的 web.config 中 <system.web> 节点中添加 <customErrors mode="On" defaultRedirect="Error"></customErrors>
c)将Views/Shared/Error.cshtml 指定为 @model HandleErrorInfo
7.2 代码演示:
web.config配置和Error.cshtml
1 <system.web> 2 <customErrors mode="On" defaultRedirect="Error"></customErrors> 3 </system.web>
1 @{ 2 Layout = null; 3 } 4 @model HandleErrorInfo 5 6 <!DOCTYPE html> //Error.cshtml 7 <html> 8 <head> 9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 10 <meta name="viewport" content="width=device-width" /> 11 <title>错误</title> 12 </head> 13 <body> 14 <hgroup> 15 <h1>错误。</h1> 16 <h2>处理你的请求时出错。</h2> 17 抱歉,控制器;@Model.ControllerName 下的 @Model.ActionName 抛出了异常:<br /> 18 详细堆栈信息如下:<br /> 19 @Model.Exception.Message 20 </hgroup> 21 </body> 22 </html>
作者:Cboii
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。
在wordpress安装、主题、插件以及开发上面有问题的,可以加入qq群:1140958614(Wp建站每日学习/交流群)进行学习和提问
如果需要建站服务,可以直接联系我的qq:185369045