MVC深度分析(一)扩展MVC内置过滤器
最近在公司项目中用MVC内置的权限过滤器实现权限控制功能,查阅以前的代码发现权限过滤接口已经被实现在其他地方,作用是用户访问系统任何页面时都要判断是否登录,如果没有登录,就会自动读取本机的域账号信息,并自动完成登录动作。现在遇到的问题是,如果新加的权限验证功能基于权限过滤器,就必须考虑过滤器的执行先后顺序,由于权限验证基于用户信息,所以我要保证用户自动登录的过滤器在权限过滤器之前被执行,但是MVC的权限过滤器默认是优先级最高的,我又不想让非权限验证的功能丢在权限过滤器中执行,又想要这个过滤器执行优先级一定高于权限过滤器,怎么办呢?看来只有通过扩展MVC内置过滤器的方式实现了。
一、初步计划
自定义一个过滤器接口IFirstFilter,它会在MVC框架中被最先调用,程序员只需要创建实现该接口的特性,就可以实现自定义过滤器。二、实现步骤
1) 重写ControllerActionInvoker的方法InvokeAction由于MVC框架的action方法调用统一通过InvokeAction执行,在这个方法中会调用MVC内置过滤器,我们通过重写它来给自定义过滤器“内置”进去。另外还自定义两个方法,GetFirstFilters方法用来通过反射特性获取自定义的特性,InvokeFirstFilters用来执行自定义的过滤器。
新建类文件UserControllerActionInvoker.cs,代码如下:
view sourceprint?01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Web;
05 using System.Web.Mvc;
06 using System.Reflection;
07
08 namespace MvcUserFilter.MVC
09 {
10 public class UserControllerActionInvoker : ControllerActionInvoker
11 {
12 public override bool InvokeAction(ControllerContext controllerContext, string actionName)
13 {
14 if (controllerContext != null && !string.IsNullOrEmpty(actionName))
15 {
16 ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
17 ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName);
18
19 if (actionDescriptor != null)
20 {
21 IList<IFirstFilter> firstFilters = GetFirstFilters(actionDescriptor);
22 FirstFilterContext firstContext = InvokeFirstFilters(controllerContext, firstFilters, actionDescriptor);
23 if (firstContext.Result != null)
24 {
25 InvokeActionResult(controllerContext, firstContext.Result);
26 return true;
27 }
28 }
29 }
30
31 return base.InvokeAction(controllerContext, actionName);
32
33 }
34
35 private IList<IFirstFilter> GetFirstFilters(ActionDescriptor actionDescriptor)
36 {
37
38 MethodInfo methodInfo = (actionDescriptor as ReflectedActionDescriptor).MethodInfo;
39
40 FilterAttribute[] typeFilters = (FilterAttribute[])methodInfo.ReflectedType.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */);
41 FilterAttribute[] methodFilters = (FilterAttribute[])methodInfo.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */);
42 List<FilterAttribute> orderedFilters = typeFilters.Concat(methodFilters).OrderBy(attr => attr.Order).ToList();
43
44 IList<IFirstFilter> firstFilters = new List<IFirstFilter>();
45
46 foreach (FilterAttribute filter in orderedFilters)
47 {
48 IFirstFilter castFilter = filter as IFirstFilter;
49 if (castFilter != null)
50 {
51 firstFilters.Add(castFilter);
52 }
53 }
54 return firstFilters;
55 }
56
57 private FirstFilterContext InvokeFirstFilters(ControllerContext controllerContext, IList<IFirstFilter> firstFilters, ActionDescriptor actionDescriptor)
58 {
59 FirstFilterContext context = new FirstFilterContext(controllerContext, actionDescriptor);
60 foreach (IFirstFilter filter in firstFilters)
61 {
62 &nbs
补充:软件开发 , Java ,