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中的参数是怎么被赋值的

posted @   异地远程联网技术  阅读(6115)  评论(5编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示