Пример #1
0
 public override ValueTask <IActionResult> Execute(
     IActionResultTypeMapper mapper,
     ObjectMethodExecutor executor,
     object controller,
     object[] arguments)
 {
     executor.Execute(controller, arguments);
     return(new ValueTask <IActionResult>(new EmptyResult()));
 }
Пример #2
0
        public static Task <object> ExecuteAsync(
            ObjectMethodExecutor actionMethodExecutor,
            object instance,
            IDictionary <string, object> actionArguments)
        {
            var orderedArguments = PrepareArguments(actionArguments, actionMethodExecutor.MethodInfo.GetParameters());

            return(ExecuteAsync(actionMethodExecutor, instance, orderedArguments));
        }
Пример #3
0
            public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments)
            {
                // Async method returning awaitable-of-nonvoid
                var returnValue = await executor.ExecuteAsync(controller, arguments);

                var actionResult = ConvertToActionResult(returnValue, executor.MethodReturnType);

                return(actionResult);
            }
Пример #4
0
            public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments)
            {
                // Async method returning awaitable-of-IActionResult (e.g., Task<ViewResult>)
                // We have to use ExecuteAsync because we don't know the awaitable's type at compile time.
                var actionResult = (IActionResult)await executor.ExecuteAsync(controller, arguments);

                EnsureActionResultNotNull(executor, actionResult);
                return(actionResult);
            }
Пример #5
0
            public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments)
            {
                // Async method returning Task<IActionResult>
                // Avoid extra allocations by calling Execute rather than ExecuteAsync and casting to Task<IActionResult>.
                var returnValue  = executor.Execute(controller, arguments);
                var actionResult = await(Task <IActionResult>) returnValue;

                EnsureActionResultNotNull(executor, actionResult);

                return(actionResult);
            }
            public override ValueTask <IActionResult> Execute(
                IActionResultTypeMapper mapper,
                ObjectMethodExecutor executor,
                object controller,
                object[] arguments)
            {
                var actionResult = (IActionResult)executor.Execute(controller, arguments);

                EnsureActionResultNotNull(executor, actionResult);

                return(new ValueTask <IActionResult>(actionResult));
            }
            public override ValueTask <IActionResult> Execute(
                IActionResultTypeMapper mapper,
                ObjectMethodExecutor executor,
                object controller,
                object[] arguments)
            {
                // Sync method returning arbitrary object
                var returnValue  = executor.Execute(controller, arguments);
                var actionResult = ConvertToActionResult(mapper, returnValue, executor.MethodReturnType);

                return(new ValueTask <IActionResult>(actionResult));
            }
Пример #8
0
        public virtual async Task InvokeAsync()
        {
            var cacheEntry = _controllerActionInvokerCache.GetCacheEntry(Context);

            _filters = _controllerActionInvokerCache.GetFiltersFromEntry(cacheEntry, Context);
            _controllerActionMethodExecutor = cacheEntry.ActionMethodExecutor;
            _cursor = new FilterCursor(_filters);

            Context.ModelState.MaxAllowedErrors = _maxModelValidationErrors;

            await InvokeAllAuthorizationFiltersAsync();

            // If Authorization Filters return a result, it's a short circuit because
            // authorization failed. We don't execute Result Filters around the result.
            Debug.Assert(_authorizationContext != null);
            if (_authorizationContext.Result != null)
            {
                await InvokeResultAsync(_authorizationContext.Result);

                return;
            }

            try
            {
                await InvokeAllResourceFiltersAsync();
            }
            finally
            {
                // Release the instance after all filters have run. We don't need to surround
                // Authorizations filters because the instance will be created much later than
                // that.
                if (Instance != null)
                {
                    ReleaseInstance(Instance);
                }
            }

            // We've reached the end of resource filters. If there's an unhandled exception on the context then
            // it should be thrown and middleware has a chance to handle it.
            Debug.Assert(_resourceExecutedContext != null);
            if (_resourceExecutedContext.Exception != null && !_resourceExecutedContext.ExceptionHandled)
            {
                if (_resourceExecutedContext.ExceptionDispatchInfo == null)
                {
                    throw _resourceExecutedContext.Exception;
                }
                else
                {
                    _resourceExecutedContext.ExceptionDispatchInfo.Throw();
                }
            }
        }
        public static ActionMethodExecutor GetExecutor(ObjectMethodExecutor executor)
        {
            for (var i = 0; i < Executors.Length; i++)
            {
                if (Executors[i].CanExecute(executor))
                {
                    return(Executors[i]);
                }
            }

            Debug.Fail("Should not get here");
            throw new Exception();
        }
Пример #10
0
 internal ControllerActionInvokerCacheEntry(
     FilterItem[] cachedFilters,
     Func <ControllerContext, object> controllerFactory,
     Action <ControllerContext, object> controllerReleaser,
     ControllerBinderDelegate controllerBinderDelegate,
     ObjectMethodExecutor actionMethodExecutor)
 {
     ControllerFactory        = controllerFactory;
     ControllerReleaser       = controllerReleaser;
     ControllerBinderDelegate = controllerBinderDelegate;
     CachedFilters            = cachedFilters;
     ActionMethodExecutor     = actionMethodExecutor;
 }
        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);
        }
        public Entry GetCacheEntry(ControllerContext controllerContext)
        {
            var cache            = CurrentCache;
            var actionDescriptor = controllerContext.ActionDescriptor;

            Entry entry;

            if (cache.Entries.TryGetValue(actionDescriptor, out entry))
            {
                return(entry);
            }

            var executor = ObjectMethodExecutor.Create(actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo);

            var items = new List <FilterItem>(actionDescriptor.FilterDescriptors.Count);

            for (var i = 0; i < actionDescriptor.FilterDescriptors.Count; i++)
            {
                items.Add(new FilterItem(actionDescriptor.FilterDescriptors[i]));
            }

            ExecuteProviders(controllerContext, items);

            var filters = ExtractFilters(items);

            var allFiltersCached = true;

            for (var i = 0; i < items.Count; i++)
            {
                var item = items[i];
                if (!item.IsReusable)
                {
                    item.Filter      = null;
                    allFiltersCached = false;
                }
            }

            if (allFiltersCached)
            {
                entry = new Entry(filters, null, executor);
            }
            else
            {
                entry = new Entry(null, items, executor);
            }

            cache.Entries.TryAdd(actionDescriptor, entry);
            return(entry);
        }
        public (ControllerActionInvokerCacheEntry cacheEntry, IFilterMetadata[] filters) GetCachedResult(ControllerContext controllerContext)
        {
            var cache            = CurrentCache;
            var actionDescriptor = controllerContext.ActionDescriptor;

            IFilterMetadata[] filters;
            if (!cache.Entries.TryGetValue(actionDescriptor, out var cacheEntry))
            {
                var filterFactoryResult = FilterFactory.GetAllFilters(_filterProviders, controllerContext);
                filters = filterFactoryResult.Filters;

                var parameterDefaultValues = ParameterDefaultValues
                                             .GetParameterDefaultValues(actionDescriptor.MethodInfo);

                var objectMethodExecutor = ObjectMethodExecutor.Create(
                    actionDescriptor.MethodInfo,
                    actionDescriptor.ControllerTypeInfo,
                    parameterDefaultValues);

                var controllerFactory     = _controllerFactoryProvider.CreateControllerFactory(actionDescriptor);
                var controllerReleaser    = _controllerFactoryProvider.CreateControllerReleaser(actionDescriptor);
                var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate(
                    _parameterBinder,
                    _modelBinderFactory,
                    _modelMetadataProvider,
                    actionDescriptor,
                    _mvcOptions);

                var actionMethodExecutor = ActionMethodExecutor.GetExecutor(objectMethodExecutor);

                cacheEntry = new ControllerActionInvokerCacheEntry(
                    filterFactoryResult.CacheableFilters,
                    controllerFactory,
                    controllerReleaser,
                    propertyBinderFactory,
                    objectMethodExecutor,
                    actionMethodExecutor);
                cacheEntry = cache.Entries.GetOrAdd(actionDescriptor, cacheEntry);
            }
            else
            {
                // Filter instances from statically defined filter descriptors + from filter providers
                filters = FilterFactory.CreateUncachedFilters(_filterProviders, controllerContext, cacheEntry.CachedFilters);
            }

            return(cacheEntry, filters);
        }
Пример #14
0
        public ControllerActionInvokerState GetState(ControllerContext controllerContext)
        {
            // Filter instances from statically defined filter descriptors + from filter providers
            IFilterMetadata[] filters;

            var cache            = CurrentCache;
            var actionDescriptor = controllerContext.ActionDescriptor;

            Entry cacheEntry;

            if (cache.Entries.TryGetValue(actionDescriptor, out cacheEntry))
            {
                filters = GetFilters(controllerContext, cacheEntry.FilterItems);

                return(new ControllerActionInvokerState(filters, cacheEntry.ActionMethodExecutor));
            }

            var executor = ObjectMethodExecutor.Create(
                actionDescriptor.MethodInfo,
                actionDescriptor.ControllerTypeInfo);

            var staticFilterItems = new List <FilterItem>(actionDescriptor.FilterDescriptors.Count);

            for (var i = 0; i < actionDescriptor.FilterDescriptors.Count; i++)
            {
                staticFilterItems.Add(new FilterItem(actionDescriptor.FilterDescriptors[i]));
            }

            filters = GetFilters(controllerContext, staticFilterItems);

            // Cache the filter items based on the following criteria
            // 1. Are created statically (ex: via filter attributes, added to global filter list etc.)
            // 2. Are re-usable
            for (var i = 0; i < staticFilterItems.Count; i++)
            {
                var item = staticFilterItems[i];
                if (!item.IsReusable)
                {
                    item.Filter = null;
                }
            }
            cacheEntry = new Entry(staticFilterItems, executor);
            cache.Entries.TryAdd(actionDescriptor, cacheEntry);

            return(new ControllerActionInvokerState(filters, cacheEntry.ActionMethodExecutor));
        }
 // Catch-all for sync methods
 protected override bool CanExecute(ObjectMethodExecutor executor) => !executor.IsMethodAsync;
Пример #16
0
        private bool IsConvertibleToActionResult(ObjectMethodExecutor executor)
        {
            var resultType = executor.AsyncResultType ?? executor.MethodReturnType;

            return(typeof(IConvertToActionResult).IsAssignableFrom(resultType));
        }
 public Entry(List<FilterItem> items, ObjectMethodExecutor executor)
 {
     FilterItems = items;
     ActionMethodExecutor = executor;
 }
Пример #18
0
        public static ObjectMethodExecutor Create(MethodInfo methodInfo, TypeInfo targetTypeInfo)
        {
            var executor = new ObjectMethodExecutor(methodInfo, targetTypeInfo);

            return(executor);
        }
 protected override bool CanExecute(ObjectMethodExecutor executor)
 => !executor.IsMethodAsync && typeof(IActionResult).IsAssignableFrom(executor.MethodReturnType);
Пример #20
0
        public ControllerActionInvoker(
            ControllerActionInvokerCache cache,
            IControllerFactory controllerFactory,
            IControllerArgumentBinder controllerArgumentBinder,
            ILogger logger,
            DiagnosticSource diagnosticSource,
            ActionContext actionContext,
            IReadOnlyList <IValueProviderFactory> valueProviderFactories,
            int maxModelValidationErrors)
        {
            if (cache == null)
            {
                throw new ArgumentNullException(nameof(cache));
            }

            if (controllerFactory == null)
            {
                throw new ArgumentNullException(nameof(controllerFactory));
            }

            if (controllerArgumentBinder == null)
            {
                throw new ArgumentNullException(nameof(controllerArgumentBinder));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (diagnosticSource == null)
            {
                throw new ArgumentNullException(nameof(diagnosticSource));
            }

            if (actionContext == null)
            {
                throw new ArgumentNullException(nameof(actionContext));
            }

            if (valueProviderFactories == null)
            {
                throw new ArgumentNullException(nameof(valueProviderFactories));
            }

            _controllerFactory        = controllerFactory;
            _controllerArgumentBinder = controllerArgumentBinder;
            _logger           = logger;
            _diagnosticSource = diagnosticSource;

            _controllerContext = new ControllerContext(actionContext);
            _controllerContext.ModelState.MaxAllowedErrors = maxModelValidationErrors;

            // PERF: These are rarely going to be changed, so let's go copy-on-write.
            _controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(valueProviderFactories);

            var cacheEntry = cache.GetState(_controllerContext);

            _filters  = cacheEntry.Filters;
            _executor = cacheEntry.ActionMethodExecutor;
            _cursor   = new FilterCursor(_filters);
        }
 protected override bool CanExecute(ObjectMethodExecutor executor)
 => !executor.IsMethodAsync && executor.MethodReturnType == typeof(void);
 public abstract ValueTask <IActionResult> Execute(
     IActionResultTypeMapper mapper,
     ObjectMethodExecutor executor,
     object controller,
     object[] arguments);
 protected abstract bool CanExecute(ObjectMethodExecutor executor);
 protected override bool CanExecute(ObjectMethodExecutor executor)
 {
     // Async method returning awaitable-of - IActionResult(e.g., Task<ViewResult>)
     return(executor.IsMethodAsync && typeof(IActionResult).IsAssignableFrom(executor.AsyncResultType));
 }
 protected override bool CanExecute(ObjectMethodExecutor executor) => true;
 protected override bool CanExecute(ObjectMethodExecutor executor)
 => typeof(Task <IActionResult>).IsAssignableFrom(executor.MethodReturnType);
 protected override bool CanExecute(ObjectMethodExecutor executor)
 {
     // Async method returning void
     return(executor.IsMethodAsync && executor.AsyncResultType == typeof(void));
 }
 protected override bool CanExecute(ObjectMethodExecutor executor) => executor.MethodReturnType == typeof(Task);
Пример #29
0
 private static ObjectMethodExecutor CreateExecutor(ControllerActionDescriptor actionDescriptor)
 {
     return(ObjectMethodExecutor.Create(actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo));
 }
        private static bool IsResultIActionResult(ObjectMethodExecutor executor)
        {
            var resultType = executor.AsyncResultType ?? executor.MethodReturnType;

            return(typeof(IActionResult).IsAssignableFrom(resultType));
        }