/// <summary> /// Completes action execution, calls after actions and writes response /// </summary> private async Task CompleteActionExecution(RouteMatch match, FilterContext context, HttpResponse response, TwinoController controller, ActionDescriptor descriptor, IActionResult actionResult) { if (actionResult == null) { return; } //IActionResult actionResult = match.Route.ActionType.Invoke(controller, descriptor.Parameters.Select(x => x.Value).ToArray()) as IActionResult; context.Result = actionResult; if (match.Route.HasActionExecutedFilter) { //find controller filters IActionExecutedFilter[] filters = (IActionExecutedFilter[])match.Route.ActionType.GetCustomAttributes(typeof(IActionExecutedFilter), true); //call AfterCreated methods of controller attributes foreach (IActionExecutedFilter filter in filters) { await filter.OnExecuted(controller, descriptor, actionResult, context); } } if (match.Route.HasControllerExecutedFilter) { //find controller filters IActionExecutedFilter[] filters = (IActionExecutedFilter[])match.Route.ControllerType.GetCustomAttributes(typeof(IActionExecutedFilter), true); //call AfterCreated methods of controller attributes foreach (IActionExecutedFilter filter in filters) { await filter.OnExecuted(controller, descriptor, actionResult, context); } } await controller.CallActionExecuted(descriptor, context, actionResult); WriteResponse(response, actionResult); }