AuthorizeFilter筛选器
在Action的执行中包括两个重要的部分,一个是Action方法自己逻辑代码的执行,第二个就是Action方法的筛选器的执行。html
MVC4中筛选器都是以AOP(面向方面编程)的方式来设计的,经过对Action方法上标注相应的Attribute标签来实现。MVC4提供了四种筛选器,分别为:AuthorizationFilter、ActionFilter、ExceptionFilter和ResultFilter,他们分别对应了四个筛选器接口IAuthorizationFilter、IActionFilter、IExceptionFilter和IResultFilter。编程
这四种筛选器都有派生于一个公共的类FilterAttribute,该类指定了筛选器的执行顺序Order和是否容许多个应用AllowedMultiple。这四种筛选器默认的执行顺序为最早进行受权筛选,最后进行异常处理,中间则是ActionFilter和ResultedFilter。ide
下面是抽象类FilterAttribute的类图post

下面咱们来具体列举一下各个筛选器的做用和实现学习
从字面上咱们就能看出这是对Controller或Action方法受权的筛选器,即在Controller或Action方法执行前,首先会先执行该筛选器,若经过,才会继续执行。下面是此筛选器的简单类图ui

AuthorizeAttribute为最终受权筛选器的实现者,它实现了IAuthorizationFilter接口和FilterAttribute抽象类,接口中的OnAuthorization(AuthorizationContext filterContext)方法是最终验证受权的逻辑(其中AuthorizationContext是继承了ControllerContext类)this
-
protected virtual bool AuthorizeCore(HttpContextBase httpContext)
-
-
-
-
throw new ArgumentNullException("httpContext");
-
-
-
IPrincipal user = httpContext.User;
-
if (!user.Identity.IsAuthenticated)
-
-
-
-
-
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
-
-
-
-
-
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
-
-
-
-
-
-
AuthorizeCore方法是最终OnAuthorization()方法调用的最终逻辑,从代码能够看出,当同时指定了users和roles时,二者只有同时知足条件时才能够验证受权经过。如url
-
[
Authorize(Users="zhangsan", Roles="Admin")]
-
public ActionResult ActionMethod()
-
-
则只有用户zhangsan,且用户属于Admin角色时才能验证受权经过。spa
若验证不经过时,OnAuthorization方法内部会调用HandleUnauthorizedRequest
虚方法进行处理,代码以下:debug
-
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
-
-
-
filterContext.Result =
new HttpUnauthorizedResult();
-
该方法设置了参数上下文中ActionResult的值,用于供View展现。
咱们能够自定义Authorize筛选器,因为OnAthurization()、AuthorizeCore()和HandleUnauthorizedRequest()方法都是虚方法,咱们自定义的Authorize筛选器只须要继承AuthorizeAttribute类,重写以上三种方法,这样就能够自定义本身的验证规则和验证失败时的处理逻辑了。
IAuthorizationFilter还有其余类型的实现类,如RequireHttpsAttribute、ValidateInputAttribute都是实现了OnAuthorization()方法,来完成各自筛选器处理的。
该筛选器是在系统出现异常时触发,能够对抛出的异常进行处理。全部的ExceptionFilter筛选器都是实现自IExceptionFilter接口
-
public interface IExceptionFilter
-
-
void OnException(ExceptionContext filterContext);
-
实现OnException方法来实现对异常的自定义处理
MVC4中实现了默认的异常处理机制,源码以下
-
public virtual void OnException(ExceptionContext filterContext)
-
-
if (filterContext == null)
-
-
throw new ArgumentNullException("filterContext");
-
-
if (filterContext.IsChildAction)
-
-
-
-
-
-
-
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
-
-
-
-
-
Exception exception = filterContext.Exception;
-
-
-
-
if (new HttpException(null, exception).GetHttpCode() != 500)
-
-
-
-
-
if (!ExceptionType.IsInstanceOfType(exception))
-
-
-
-
-
string controllerName = (string)filterContext.RouteData.Values["controller"];
-
string actionName = (string)filterContext.RouteData.Values["action"];
-
HandleErrorInfo model =
new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
-
filterContext.Result =
new ViewResult
-
-
-
-
ViewData =
new ViewDataDictionary<HandleErrorInfo>(model),
-
TempData = filterContext.Controller.TempData
-
-
filterContext.ExceptionHandled =
true;
-
filterContext.HttpContext.Response.Clear();
-
filterContext.HttpContext.Response.StatusCode =
500;
-
-
-
-
-
filterContext.HttpContext.Response.TrySkipIisCustomErrors =
true;
-
Application_Start中将HandleErrorAttribute添加到全局筛选器GlobalFilterCollection中,系统即会对异常进行对应的处理。
咱们如今实现一个自定义的异常处理筛选器,在处理完后记录异常信息至日志文件中
-
public class MyExceptionHandleAttribute : HandleErrorAttribute
-
-
public MyExceptionHandleAttribute()
-
-
-
-
-
public void OnException(ExceptionContext filterContext)
-
-
base.OnException(filterContext);
-
-
log.Info(filterContext.Exception);
-
-
在GlobalFilterCollection添加MyExceptionHandleAttribute 便可使用自定义的异常筛选器来处理
ActionFilter筛选器
ActionFilter筛选器是在Action方法执行先后会触发,主要用于在Action执行先后处理一些相应的逻辑。ActionFilter的筛选器都继承于ActionFilterAttribute抽象类,而它实现了IActionFilter、IResultFilter和FilterAttribute类,结构以下

所以自定义ActionFilter筛选器只要继承ActionFilterAttribute,实现其中的方法便可。
咱们来举一个简单的例子,获取Action方法的执行时长,代码以下
-
public class DefaultController : Controller
-
-
-
public ActionResult DoWork()
-
-
-
-
-
-
public class ActionExecTimeSpanAttribute : ActionFilterAttribute
-
-
private const string executeActionTimeKey = "ActionExecBegin";
-
-
public override void OnActionExecuting(ActionExecutingContext filterContext)
-
-
base.OnActionExecuting(filterContext);
-
-
filterContext.HttpContext.Items[executeActionTimeKey] = DateTime.Now;
-
-
-
public override void OnActionExecuted(ActionExecutedContext filterContext)
-
-
-
if (filterContext.HttpContext.Items.Contains(executeActionTimeKey))
-
-
DateTime endTime = DateTime.Now;
-
DateTime beginTime = Convert.ToDateTime(filterContext.HttpContext.Items[executeActionTimeKey]);
-
TimeSpan span = endTime - beginTime;
-
double execTimeSpan = span.TotalMilliseconds;
-
log.Info(execTimeSpan +
"毫秒");
-
-
-
base.OnActionExecuted(filterContext);
-
-
ResultFilter筛选器
ResultFilter筛选器是对Action方法返回的Result结果进行执行时触发的。它也分执行前和执行后两个段执行
全部的ResultFilter都实现了IResultFilter接口和FilterAttribute类,看一下接口定义
-
public interface IResultFilter
-
-
void OnResultExecuting(ResultExecutingContext filterContext);
-
-
void OnResultExecuted(ResultExecutedContext filterContext);
-
其中OnResultExecuting和OnResultExecuted方法分别是在Result执行前、后(页面展现内容生成前、后)触发。
使用ResultFilter筛选器最典型的应用就是页面静态化,咱们之后在其余文章中在对此进行详细讲解
学习何时都不晚,从如今起咱们一块儿