protected override async Task <IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext) { if (actionExecutingContext == null) { throw new ArgumentNullException(nameof(actionExecutingContext)); } var actionMethodInfo = _descriptor.MethodInfo; var methodExecutor = GetControllerActionMethodExecutor(); var arguments = ControllerActionExecutor.PrepareArguments( actionExecutingContext.ActionArguments, actionMethodInfo.GetParameters()); Logger.ActionMethodExecuting(actionExecutingContext, arguments); var actionReturnValue = await ControllerActionExecutor.ExecuteAsync( methodExecutor, actionExecutingContext.Controller, arguments); var actionResult = CreateActionResult( actionMethodInfo.ReturnType, actionReturnValue); Logger.ActionMethodExecuted(actionExecutingContext, actionResult); return(actionResult); }
private async Task <object> ExecuteAction( Delegate methodDelegate, TestController controller, object[] actionParameters) { var executor = ObjectMethodExecutor.Create(methodDelegate.GetMethodInfo(), _controller.GetType().GetTypeInfo()); var result = await ControllerActionExecutor.ExecuteAsync( executor, controller, actionParameters); return(result); }
private async Task InvokeActionFilterAsync() { Debug.Assert(_actionExecutingContext != null); var item = _cursor.GetNextFilter <IActionFilter, IAsyncActionFilter>(); try { if (item.FilterAsync != null) { _diagnosticSource.BeforeOnActionExecution(_actionExecutingContext, item.FilterAsync); await item.FilterAsync.OnActionExecutionAsync(_actionExecutingContext, InvokeActionFilterAwaitedAsync); if (_actionExecutedContext == null) { // If we get here then the filter didn't call 'next' indicating a short circuit _logger.ActionFilterShortCircuited(item.FilterAsync); _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, _filters, _controller) { Canceled = true, Result = _actionExecutingContext.Result, }; } _diagnosticSource.AfterOnActionExecution(_actionExecutedContext, item.FilterAsync); } else if (item.Filter != null) { _diagnosticSource.BeforeOnActionExecuting(_actionExecutingContext, item.Filter); item.Filter.OnActionExecuting(_actionExecutingContext); _diagnosticSource.AfterOnActionExecuting(_actionExecutingContext, item.Filter); if (_actionExecutingContext.Result != null) { // Short-circuited by setting a result. _logger.ActionFilterShortCircuited(item.Filter); _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, _filters, _controller) { Canceled = true, Result = _actionExecutingContext.Result, }; } else { await InvokeActionFilterAsync(); Debug.Assert(_actionExecutedContext != null); _diagnosticSource.BeforeOnActionExecuted(_actionExecutedContext, item.Filter); item.Filter.OnActionExecuted(_actionExecutedContext); _diagnosticSource.BeforeOnActionExecuted(_actionExecutedContext, item.Filter); } } else { // All action filters have run, execute the action method. IActionResult result = null; try { _diagnosticSource.BeforeActionMethod( _controllerContext, _actionExecutingContext.ActionArguments, _actionExecutingContext.Controller); var actionMethodInfo = _controllerContext.ActionDescriptor.MethodInfo; var arguments = ControllerActionExecutor.PrepareArguments( _actionExecutingContext.ActionArguments, _executor); _logger.ActionMethodExecuting(_actionExecutingContext, arguments); var returnType = _executor.MethodReturnType; if (returnType == typeof(void)) { _executor.Execute(_controller, arguments); result = new EmptyResult(); } else if (returnType == typeof(Task)) { await(Task) _executor.Execute(_controller, arguments); result = new EmptyResult(); } else if (_executor.TaskGenericType == typeof(IActionResult)) { result = await(Task <IActionResult>) _executor.Execute(_controller, arguments); if (result == null) { throw new InvalidOperationException( Resources.FormatActionResult_ActionReturnValueCannotBeNull(typeof(IActionResult))); } } else if (_executor.IsTypeAssignableFromIActionResult) { if (_executor.IsMethodAsync) { result = (IActionResult)await _executor.ExecuteAsync(_controller, arguments); } else { result = (IActionResult)_executor.Execute(_controller, arguments); } if (result == null) { throw new InvalidOperationException( Resources.FormatActionResult_ActionReturnValueCannotBeNull(_executor.TaskGenericType ?? returnType)); } } else if (!_executor.IsMethodAsync) { var resultAsObject = _executor.Execute(_controller, arguments); result = new ObjectResult(resultAsObject) { DeclaredType = returnType, }; } else if (_executor.TaskGenericType != null) { var resultAsObject = await _executor.ExecuteAsync(_controller, arguments); result = new ObjectResult(resultAsObject) { DeclaredType = _executor.TaskGenericType, }; } else { // This will be the case for types which have derived from Task and Task<T> or non Task types. throw new InvalidOperationException(Resources.FormatActionExecutor_UnexpectedTaskInstance( _executor.MethodInfo.Name, _executor.MethodInfo.DeclaringType)); } _logger.ActionMethodExecuted(_actionExecutingContext, result); } finally { _diagnosticSource.AfterActionMethod( _controllerContext, _actionExecutingContext.ActionArguments, _actionExecutingContext.Controller, result); } _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, _filters, _controller) { Result = result }; } } catch (Exception exception) { // Exceptions thrown by the action method OR filters bubble back up through ActionExcecutedContext. _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, _filters, _controller) { ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) }; } Debug.Assert(_actionExecutedContext != null); }