Exemple #1
0
        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
            });
        }
Exemple #3
0
        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);
        }