MVC中的过滤器

authour: chenboyi
updatetime: 2015-05-09 09:30:30
friendly link:  

 

 

 

 

 

目录:

  1,思维导图

   2,过滤器种类(图示)

  3,全局过滤器

   4,ActionFilterAttribute

   5,AuthorizeAttribute

   6,HandleErrorAttribute

   7,自定义错误页


 

1,思维导图:

 

2,过滤器种类(图示):

mvc中的过滤器png

 

3,全局过滤器:

  程序员可以自己定义过滤器,并将其设为全局或者单个类、单个方法上得过滤器,如果要把自定义过滤器设为全局过滤器要做如下操作

  下面示例是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,ActionFilterAttribute:

 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         }

 
5,AuthorizeAttribute

  验证过滤器(用来配合实现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,自定义错误页

  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>        

 

posted on 2015-05-09 10:43  两宝程序cboii  阅读(305)  评论(0编辑  收藏  举报

导航