public RequestDelegate CreateRequestDelegate(ActionDescriptor actionDescriptor, RouteValueDictionary dataTokens) { // Fallback to action invoker extensibility so that invokers can override any default behaviors if (!_enableActionInvokers && actionDescriptor is ControllerActionDescriptor) { return(context => { RouteData routeData = null; if (dataTokens is null or { Count : 0 }) { routeData = new RouteData(context.Request.RouteValues); } else { routeData = new RouteData(); routeData.PushState(router: null, context.Request.RouteValues, dataTokens); } var actionContext = new ActionContext(context, routeData, actionDescriptor); var controllerContext = new ControllerContext(actionContext) { // PERF: These are rarely going to be changed, so let's go copy-on-write. ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(_valueProviderFactories) }; controllerContext.ModelState.MaxAllowedErrors = _maxModelValidationErrors; var(cacheEntry, filters) = _controllerActionInvokerCache.GetCachedResult(controllerContext); var invoker = new ControllerActionInvoker( _logger, _diagnosticListener, _actionContextAccessor, _mapper, controllerContext, cacheEntry, filters); return invoker.InvokeAsync(); });
public async Task Invoke_UsesDefaultValuesIfNotBound() { // Arrange var actionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = typeof(TestController).GetTypeInfo(), BoundProperties = new List<ParameterDescriptor>(), MethodInfo = typeof(TestController).GetTypeInfo() .DeclaredMethods .First(m => m.Name.Equals("ActionMethodWithDefaultValues", StringComparison.Ordinal)), Parameters = new List<ParameterDescriptor> { new ParameterDescriptor { Name = "value", ParameterType = typeof(int), BindingInfo = new BindingInfo(), } }, FilterDescriptors = new List<FilterDescriptor>() }; var binder = new Mock<IModelBinder>(); binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Returns(Task.FromResult<ModelBindingResult>(result: null)); var context = new Mock<HttpContext>(); context.SetupGet(c => c.Items) .Returns(new Dictionary<object, object>()); context.Setup(c => c.RequestServices.GetService(typeof(ITempDataDictionary))) .Returns(new Mock<ITempDataDictionary>().Object); context.Setup(c => c.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(new NullLoggerFactory()); var actionContext = new ActionContext(context.Object, new RouteData(), actionDescriptor); var controllerFactory = new Mock<IControllerFactory>(); controllerFactory.Setup(c => c.CreateController(It.IsAny<ActionContext>())) .Returns(new TestController()); var metadataProvider = new EmptyModelMetadataProvider(); var invoker = new ControllerActionInvoker( actionContext, new List<IFilterProvider>(), controllerFactory.Object, actionDescriptor, new IInputFormatter[0], new IOutputFormatter[0], new DefaultControllerActionArgumentBinder( metadataProvider, new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider)), new IModelBinder[] { binder.Object }, new IModelValidatorProvider[0], new IValueProviderFactory[0], new MockScopedInstance<ActionBindingContext>(), Mock.Of<ITempDataDictionary>(), new NullLoggerFactory(), 200); // Act await invoker.InvokeAsync(); // Assert Assert.Equal(5, context.Object.Items["Result"]); }