try { AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor); if (authContext.Result != null) { // the auth filter signaled that we should let it short-circuit the request InvokeActionResult(controllerContext, authContext.Result); } else { if (controllerContext.Controller.ValidateRequest) { ValidateRequest(controllerContext); }
IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor); ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters); InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result); } } catch (ThreadAbortException) { // This type of exception occurs as a result of Response.Redirect(), but we special-case so that // the filters don"t see this as an error. throw; } catch (Exception ex) { // something blew up, so execute the exception filters ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex); if (!exceptionContext.ExceptionHandled) { throw; } InvokeActionResult(controllerContext, exceptionContext.Result); }
return true; }
// notify controller that no method matched return false; }
用来验证该方法是否可以执行,以下几种情况经不会通过,(1)方法是静态方法(2)方法的实例类型不是ControllerBase(3)是否包含泛型参数如 public ActionResult Index<T>()是非法的,但 public ActionResult Index(List<string> aa)是合法(4)参数中不能含有Ref和out。 这篇文章说的很散,我们需要注意一点微软在mvc里面缓存做的很好了,在前面个将获取ControllerTyper时它是有缓存的,一次读取当前程序集所有的ControllerType,在这里提到了一个DescriptorCache 缓存每次调用的ControllerType->ReflectedControllerDescriptor,而ReflectedControllerDescriptor实例会一次去读该Controller的所有Action方法;这里还有一个ReflectedAttributeCache,缓存每次调用MethodInfo的所有特性(ActionMethodSelectorAttribute、ActionNameSelectorAttribute、FilterAttribute),当然FilterAttribute特性还可以在类上面。