MVC中Action的執行過程


接着上一篇:MVC控制器的激活過程

一、代碼現行,該偽代碼大致解析了Action的執行的過程

try 
{ 
   Run each IAuthorizationFilter's OnAuthorization() method 
  
   if(none of the IAuthorizationFilters cancelled execution)  
   { 
      Run each IActionFilter's OnActionExecuting() method 
      Run the action method 
      Run each IActionFilter's OnActionExecuted() method (in reverse order) 
  
      Run each IResultFilter's OnResultExecuting() method 
      Run the action result  
      Run each IResultFilter's OnResultExecuted() method (in reverse order) 
   } 
   else
   { 
      Run any action result set by the authorization filters 
   } 
} 
catch(exception not handled by any action or result filter)  
{ 
   Run each IExceptionFilter's OnException() method 
   Run any action result set by the exception filters 
}

二、返回主戰場Action執行方法中

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
= this.GetControllerDescriptor(controllerContext);
//描述了相關Action的相關信息 ActionDescriptor actionDescriptor
= this.FindAction(controllerContext, controllerDescriptor, actionName); if (actionDescriptor != null) {
//獲取該action的所有Filter FilterInfo filters
= this.GetFilters(controllerContext, actionDescriptor); try { AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor); if (authorizationContext.Result != null) { this.InvokeActionResult(controllerContext, authorizationContext.Result); } else { if (controllerContext.Controller.ValidateRequest) {
//地球人應該知道這個東西干嘛的,你知道嗎? ControllerActionInvoker.ValidateRequest(controllerContext); } IDictionary
<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor); ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues); this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result); } } catch (ThreadAbortException) { throw; } catch (Exception exception) { ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, exception); if (!exceptionContext.ExceptionHandled) { throw; } this.InvokeActionResult(controllerContext, exceptionContext.Result); } return true; } return false; }
//上面的授權過程 
AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor); if (authorizationContext.Result != null) { this.InvokeActionResult(controllerContext, authorizationContext.Result); }

protected virtual AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor)
{
    AuthorizationContext authorizationContext = new AuthorizationContext(controllerContext, actionDescriptor);
    foreach (IAuthorizationFilter current in filters)
    {
        current.OnAuthorization(authorizationContext);//很顯然我們在自定義IAuthorizationFilter時,會去做事情在這里定義的。如果
  //此過程,authorizationContext的Result 被你給賦值了,那么所有的其他授權認證將會終止,系統將全力執行 this.InvokeActionResult(controllerContext, authorizationContext.Result);
if (authorizationContext.Result != null) { break; } } return authorizationContext; }

三、Action連同過濾器的執行,上面談了授權過濾器的執行

IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor);
ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues);
this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);
protected virtual IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
    Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    ParameterDescriptor[] parameters = actionDescriptor.GetParameters();
    ParameterDescriptor[] array = parameters;
    for (int i = 0; i < array.Length; i++)
    {
        ParameterDescriptor parameterDescriptor = array[i];
        dictionary[parameterDescriptor.ParameterName] = this.GetParameterValue(controllerContext, parameterDescriptor);
    }
    return dictionary;
}
protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
{
    Type parameterType = parameterDescriptor.ParameterType;
    IModelBinder modelBinder = this.GetModelBinder(parameterDescriptor);
    IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
    string modelName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
    Predicate<string> propertyFilter = ControllerActionInvoker.GetPropertyFilter(parameterDescriptor);
    ModelBindingContext bindingContext = new ModelBindingContext
    {
        FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null,
        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
        ModelName = modelName,
        ModelState = controllerContext.Controller.ViewData.ModelState,
        PropertyFilter = propertyFilter,
        ValueProvider = valueProvider
    };
    object obj = modelBinder.BindModel(controllerContext, bindingContext);
    return obj ?? parameterDescriptor.DefaultValue;
}
private IModelBinder GetModelBinder(ParameterDescriptor parameterDescriptor)
{
//action參數附帶綁定信息了沒?如果沒有采用系統默認的方式進行綁定
return parameterDescriptor.BindingInfo.Binder ?? this.Binders.GetBinder(parameterDescriptor.ParameterType); }
private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder)
{
    IModelBinder modelBinder = this._modelBinderProviders.GetBinder(modelType);
    if (modelBinder != null)
    {
        return modelBinder;
    }
    if (this._innerDictionary.TryGetValue(modelType, out modelBinder))
    {
        return modelBinder;
    }
    modelBinder = ModelBinders.GetBinderFromAttributes(modelType, () => string.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderDictionary_MultipleAttributes, new object[]
    {
        modelType.FullName
    }));
    return modelBinder ?? fallbackBinder;
}
private static ModelBinderDictionary CreateDefaultBinderDictionary()
{
    return new ModelBinderDictionary
    {
        
        {
            typeof(HttpPostedFileBase),
            new HttpPostedFileBaseModelBinder()
        },
        
        {
            typeof(byte[]),
            new ByteArrayModelBinder()
        },
        
        {
            typeof(Binary),
            new LinqBinaryModelBinder()
        },
        
        {
            typeof(CancellationToken),
            new CancellationTokenModelBinder()
        }
    };
}

下一篇: Action中的參數是怎么被賦值的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM