深入分析ASP.NET Mvc 1.0 – 3. Controller.Execute(Request)-ActionInvoker.InvokeAction()
上次講到Controller中的ExecuteCore方法分為三個部執行:
TempData.Load(ControllerContext, TempDataProvider)
ActionInvoker.InvokeAction(ControllerContext, actionName)
TempData.Save(ControllerContext, TempDataProvider)
其中第1, 第3是關於TempData的Load與Save操作,在上一篇有已過深入的分析,這裡 只分析ActionInvoker.InvokeAction(ControllerContext, actionName) ,首先看一下 InvokeAction方法的源碼:
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) {
if (controllerContext == null) {
throw new ArgumentNullException("controllerContext");
}
if (String.IsNullOrEmpty(actionName)) {
throw new ArgumentException (MvcResources.Common_NullOrEmpty, "actionName");
}
ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
ActionDescriptor actionDescriptor = FindAction (controllerContext, controllerDescriptor, actionName);
if (actionDescriptor != null) {
FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
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.HttpContext.Request);
}
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;
}