private async Task InvokeAllActionFiltersAsync() { _cursor.SetStage(FilterStage.ActionFilters); Debug.Assert(_resourceExecutingContext != null); ActionBindingContext = new ActionBindingContext(); ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( _resourceExecutingContext.ValidatorProviders); var valueProviderFactoryContext = new ValueProviderFactoryContext( ActionContext.HttpContext, ActionContext.RouteData.Values); ActionBindingContext.ValueProvider = CompositeValueProvider.Create( _resourceExecutingContext.ValueProviderFactories, valueProviderFactoryContext); Instance = CreateInstance(); var arguments = await GetActionArgumentsAsync(ActionContext, ActionBindingContext); _actionExecutingContext = new ActionExecutingContext( ActionContext, _filters, arguments, Instance); await InvokeActionFilterAsync(); }
private static ActionBindingContext GetActionBindingContext(MvcOptions options, ActionContext actionContext) { var valueProviderFactoryContext = new ValueProviderFactoryContext( actionContext.HttpContext, actionContext.RouteData.Values); var valueProvider = CompositeValueProvider.Create( options.ValueProviderFactories, valueProviderFactoryContext); return(new ActionBindingContext() { InputFormatters = options.InputFormatters, OutputFormatters = options.OutputFormatters, // Not required for model binding. ValidatorProvider = new TestModelValidatorProvider(options.ModelValidatorProviders), ModelBinder = new CompositeModelBinder(options.ModelBinders), ValueProvider = valueProvider }); }
private async Task <ResourceExecutedContext> InvokeResourceFilterAsync() { Debug.Assert(_resourceExecutingContext != null); if (_resourceExecutingContext.Result != null) { // If we get here, it means that an async filter set a result AND called next(). This is forbidden. var message = Resources.FormatAsyncResourceFilter_InvalidShortCircuit( typeof(IAsyncResourceFilter).Name, nameof(ResourceExecutingContext.Result), typeof(ResourceExecutingContext).Name, typeof(ResourceExecutionDelegate).Name); throw new InvalidOperationException(message); } var item = _cursor.GetNextFilter <IResourceFilter, IAsyncResourceFilter>(); try { if (item.FilterAsync != null) { await item.FilterAsync.OnResourceExecutionAsync( _resourceExecutingContext, InvokeResourceFilterAsync); if (_resourceExecutedContext == null) { // If we get here then the filter didn't call 'next' indicating a short circuit if (_resourceExecutingContext.Result != null) { _logger.LogVerbose( ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); await InvokeResultAsync(_resourceExecutingContext.Result); } _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Canceled = true, Result = _resourceExecutingContext.Result, }; } } else if (item.Filter != null) { item.Filter.OnResourceExecuting(_resourceExecutingContext); if (_resourceExecutingContext.Result != null) { // Short-circuited by setting a result. _logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); await InvokeResultAsync(_resourceExecutingContext.Result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Canceled = true, Result = _resourceExecutingContext.Result, }; } else { item.Filter.OnResourceExecuted(await InvokeResourceFilterAsync()); } } else { // We've reached the end of resource filters, so move to setting up state to invoke model // binding. ActionBindingContext = new ActionBindingContext(); ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; ActionBindingContext.OutputFormatters = _resourceExecutingContext.OutputFormatters; ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( _resourceExecutingContext.ValidatorProviders); var valueProviderFactoryContext = new ValueProviderFactoryContext( ActionContext.HttpContext, ActionContext.RouteData.Values); ActionBindingContext.ValueProvider = CompositeValueProvider.Create( _resourceExecutingContext.ValueProviderFactories, valueProviderFactoryContext); // >> ExceptionFilters >> Model Binding >> ActionFilters >> Action await InvokeAllExceptionFiltersAsync(); // If Exception Filters provide a result, it's a short-circuit due to an exception. // We don't execute Result Filters around the result. Debug.Assert(_exceptionContext != null); if (_exceptionContext.Result != null) { // This means that exception filters returned a result to 'handle' an error. // We're not interested in seeing the exception details since it was handled. await InvokeResultAsync(_exceptionContext.Result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Result = _exceptionContext.Result, }; } else if (_exceptionContext.Exception != null) { // If we get here, this means that we have an unhandled exception. // Exception filted didn't handle this, so send it on to resource filters. _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters); // Preserve the stack trace if possible. _resourceExecutedContext.Exception = _exceptionContext.Exception; if (_exceptionContext.ExceptionDispatchInfo != null) { _resourceExecutedContext.ExceptionDispatchInfo = _exceptionContext.ExceptionDispatchInfo; } } else { // We have a successful 'result' from the action or an Action Filter, so run // Result Filters. Debug.Assert(_actionExecutedContext != null); var result = _actionExecutedContext.Result; // >> ResultFilters >> (Result) await InvokeAllResultFiltersAsync(result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Result = _resultExecutedContext.Result, }; } } } catch (Exception exception) { _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) }; } Debug.Assert(_resourceExecutedContext != null); return(_resourceExecutedContext); }