Action调用过程分析

来源:互联网 发布:hadoop 8032端口 编辑:程序博客网 时间:2024/05/08 05:33

1. 入口   Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler

        平台调用RouteAsync方法

        public async Task RouteAsync([NotNull] RouteContext context)        {


        try            {                context.RouteData = newRouteData; //                if (_telemetry.IsEnabled("Microsoft.AspNet.Mvc.BeforeAction"))                {                    _telemetry.WriteTelemetry(                        "Microsoft.AspNet.Mvc.BeforeAction",                        new { actionDescriptor, httpContext = context.HttpContext, routeData = context.RouteData});                }                using (_logger.BeginScope("ActionId: {ActionId}", actionDescriptor.Id))                {                    _logger.LogVerbose("Executing action {ActionDisplayName}", actionDescriptor.DisplayName);                    await InvokeActionAsync(context, actionDescriptor); //调用                    context.IsHandled = true;                }            }            finally            {                if (_telemetry.IsEnabled("Microsoft.AspNet.Mvc.AfterAction"))                {                    _telemetry.WriteTelemetry(                        "Microsoft.AspNet.Mvc.AfterAction",                        new { actionDescriptor, httpContext = context.HttpContext });                }                if (!context.IsHandled)                {                    context.RouteData = oldRouteData;                }            }


     调用该类的InvokeActionAsync,生成ActionContext,通过_actionInvokerFactory创建Invoker,调用invoker.InvokeAsync()

           

        private Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor)        {            var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor);            _actionContextAccessor.ActionContext = actionContext;                        var invoker = _actionInvokerFactory.CreateInvoker(actionContext);            if (invoker == null)            {                throw new InvalidOperationException(                    Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(                        actionDescriptor.DisplayName));            }            return invoker.InvokeAsync();        }


2. Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker

    

        public virtual async Task InvokeAsync()        {        //....            if (_authorizationContext.Result != null)            {                await InvokeResultAsync(_authorizationContext.Result);                return;            }
            try            {                await InvokeAllResourceFiltersAsync();            }


3.Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker

          

        protected override async Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext)        {            var actionMethodInfo = _descriptor.MethodInfo;            var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(                actionMethodInfo,                actionExecutingContext.Controller,                actionExecutingContext.ActionArguments);            var actionResult = CreateActionResult(                actionMethodInfo.ReturnType,                actionReturnValue);            return actionResult;        }


4.Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor

        public static Task<object> ExecuteAsync(            MethodInfo actionMethodInfo,            object instance,            IDictionary<string, object> actionArguments)        {            var orderedArguments = PrepareArguments(actionArguments, actionMethodInfo.GetParameters());            return ExecuteAsync(actionMethodInfo, instance, orderedArguments);        }
</pre><pre class="csharp" name="code">        public static Task<object> ExecuteAsync(            MethodInfo actionMethodInfo,            object instance,            object[] orderedActionArguments)        {            object invocationResult = null;            try            {                invocationResult = actionMethodInfo.Invoke(instance, orderedActionArguments);            }


5. 调用Controller相应的Action方法

    

调用过程如下图所示:Action调用流程图


0 0