当前位置:编程学习 > JAVA >>

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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,