예제 #1
0
        private static ActionContext CreateMockActionContext(
            IEnumerable<IOutputFormatter> outputFormatters,
            HttpResponse response = null,
            string requestAcceptHeader = "application/*",
            string requestContentType = "application/json",
            string requestAcceptCharsetHeader = "",
            bool respectBrowserAcceptHeader = false,
            bool setupActionBindingContext = true)
        {
            var httpContext = new Mock<HttpContext>();
            if (response != null)
            {
                httpContext.Setup(o => o.Response).Returns(response);
            }

            var content = "{name: 'Person Name', Age: 'not-an-age'}";
            var contentBytes = Encoding.UTF8.GetBytes(content);

            var request = new DefaultHttpContext().Request;
            request.Headers["Accept-Charset"] = requestAcceptCharsetHeader;
            request.Headers["Accept"] = requestAcceptHeader;
            request.ContentType = requestContentType;
            request.Body = new MemoryStream(contentBytes);

            httpContext.Setup(o => o.Request).Returns(request);
            httpContext.Setup(o => o.RequestServices).Returns(GetServiceProvider());

            var optionsAccessor = new MockMvcOptionsAccessor();
            foreach (var formatter in outputFormatters)
            {
                optionsAccessor.Options.OutputFormatters.Add(formatter);
            }

            optionsAccessor.Options.RespectBrowserAcceptHeader = respectBrowserAcceptHeader;
            httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
                .Returns(optionsAccessor);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger<ObjectResult>)))
                .Returns(new Mock<ILogger<ObjectResult>>().Object);

            ActionBindingContext actionBindingContext = null;
            if (setupActionBindingContext)
            {
                actionBindingContext = new ActionBindingContext { OutputFormatters = outputFormatters.ToList() };
            }
            
            httpContext.Setup(o => o.RequestServices.GetService(typeof(IActionBindingContextAccessor)))
                    .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext });

            return new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
        }
예제 #2
0
        private static Controller GetController(IModelBinder binder, IValueProvider provider)
        {
            var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var httpContext = new DefaultHttpContext();
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary());
            var tempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>());

            var bindingContext = new ActionBindingContext()
            {
                ModelBinder = binder,
                ValueProvider = provider,
                ValidatorProvider = new DataAnnotationsModelValidatorProvider()
            };

            return new TestableController()
            {
                ActionContext = actionContext,
                BindingContext = bindingContext,
                MetadataProvider = metadataProvider,
                ViewData = viewData,
                TempData = tempData,
                ObjectValidator = new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider)
            };
        }
 protected override Task<IDictionary<string, object>> BindActionArgumentsAsync(
     ActionContext context,
     ActionBindingContext bindingContext)
 {
     return _argumentBinder.BindActionArgumentsAsync(context, bindingContext, Instance);
 }
예제 #4
0
 protected override Task <IDictionary <string, object> > BindActionArgumentsAsync(
     ActionContext context,
     ActionBindingContext bindingContext)
 {
     return(_argumentBinder.BindActionArgumentsAsync(context, bindingContext, Instance));
 }
        public async Task BindActionArgumentsAsync_SetsMultipleControllerProperties()
        {
            // Arrange
            var boundPropertyTypes = new Dictionary <string, Type>
            {
                { nameof(TestController.ArrayProperty), typeof(string[]) },                // Skipped
                { nameof(TestController.CollectionProperty), typeof(List <string>) },
                { nameof(TestController.NonCollectionProperty), typeof(Person) },          // Skipped
                { nameof(TestController.NullCollectionProperty), typeof(List <string>) },  // Skipped
                { nameof(TestController.StringProperty), typeof(string) },
            };
            var inputPropertyValues = new Dictionary <string, object>
            {
                { nameof(TestController.ArrayProperty), new string[] { "hello", "world" } },
                { nameof(TestController.CollectionProperty), new List <string> {
                      "hello", "world"
                  } },
                { nameof(TestController.NonCollectionProperty), new Person {
                      Name = "Fred"
                  } },
                { nameof(TestController.NullCollectionProperty), new List <string> {
                      "hello", "world"
                  } },
                { nameof(TestController.StringProperty), "Hello" },
            };
            var expectedPropertyValues = new Dictionary <string, object>
            {
                { nameof(TestController.ArrayProperty), new string[] { "goodbye" } },
                { nameof(TestController.CollectionProperty), new List <string> {
                      "hello", "world"
                  } },
                { nameof(TestController.NonCollectionProperty), new Person {
                      Name = "Ginger"
                  } },
                { nameof(TestController.NullCollectionProperty), null },
                { nameof(TestController.StringProperty), "Hello" },
            };

            var actionDescriptor = GetActionDescriptor();

            foreach (var keyValuePair in boundPropertyTypes)
            {
                actionDescriptor.BoundProperties.Add(
                    new ParameterDescriptor
                {
                    Name          = keyValuePair.Key,
                    BindingInfo   = new BindingInfo(),
                    ParameterType = keyValuePair.Value,
                });
            }

            var actionContext  = GetActionContext(actionDescriptor);
            var argumentBinder = GetArgumentBinder();
            var controller     = new TestController();
            var binder         = new Mock <IModelBinder>();

            binder
            .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Returns <ModelBindingContext>(bindingContext =>
            {
                object model;
                var isModelSet = inputPropertyValues.TryGetValue(bindingContext.ModelName, out model);
                return(Task.FromResult(new ModelBindingResult(model, bindingContext.ModelName, isModelSet)));
            });
            var actionBindingContext = new ActionBindingContext
            {
                ModelBinder = binder.Object,
            };

            // Act
            var result = await argumentBinder.BindActionArgumentsAsync(actionContext, actionBindingContext, controller);

            // Assert
            Assert.Equal(new string[] { "goodbye" }, controller.ArrayProperty);                 // Skipped
            Assert.Equal(new List <string> {
                "hello", "world"
            }, controller.CollectionProperty);
            Assert.Equal(new Person {
                Name = "Ginger"
            }, controller.NonCollectionProperty);                                               // Skipped
            Assert.Null(controller.NullCollectionProperty);                                     // Skipped
            Assert.Null(controller.UntouchedProperty);                                          // Not bound
            Assert.Equal("Hello", controller.StringProperty);
        }
        public void CreateController_SetsBindingContext()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
            };
            var bindingContext = new ActionBindingContext();

            var services = GetServices();
            services.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value = bindingContext;
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act
            var result = factory.CreateController(context);

            // Assert
            var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
            Assert.Same(bindingContext, controller.BindingContext);
        }
예제 #7
0
        private static ActionContext CreateMockActionContext(
            IEnumerable <IOutputFormatter> outputFormatters,
            HttpResponse response             = null,
            string requestAcceptHeader        = "application/*",
            string requestContentType         = "application/json",
            string requestAcceptCharsetHeader = "",
            bool respectBrowserAcceptHeader   = false,
            bool setupActionBindingContext    = true)
        {
            var httpContext = new Mock <HttpContext>();

            if (response != null)
            {
                httpContext.Setup(o => o.Response).Returns(response);
            }

            var content      = "{name: 'Person Name', Age: 'not-an-age'}";
            var contentBytes = Encoding.UTF8.GetBytes(content);

            var request = new DefaultHttpContext().Request;

            request.Headers["Accept-Charset"] = requestAcceptCharsetHeader;
            request.Headers["Accept"]         = requestAcceptHeader;
            request.ContentType = requestContentType;
            request.Body        = new MemoryStream(contentBytes);

            httpContext.Setup(o => o.Request).Returns(request);
            httpContext.Setup(o => o.RequestServices).Returns(GetServiceProvider());

            var optionsAccessor = new MockMvcOptionsAccessor();

            foreach (var formatter in outputFormatters)
            {
                optionsAccessor.Options.OutputFormatters.Add(formatter);
            }

            optionsAccessor.Options.RespectBrowserAcceptHeader = respectBrowserAcceptHeader;
            httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions <MvcOptions>)))
            .Returns(optionsAccessor);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger <ObjectResult>)))
            .Returns(new Mock <ILogger <ObjectResult> >().Object);

            var mockActionBindingContext = new Mock <IScopedInstance <ActionBindingContext> >();

            ActionBindingContext bindingContext = null;

            if (setupActionBindingContext)
            {
                bindingContext = new ActionBindingContext {
                    OutputFormatters = outputFormatters.ToList()
                };
            }

            mockActionBindingContext
            .SetupGet(o => o.Value)
            .Returns(bindingContext);

            httpContext.Setup(o => o.RequestServices.GetService(typeof(IScopedInstance <ActionBindingContext>)))
            .Returns(mockActionBindingContext.Object);

            return(new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()));
        }
 protected override Task<IDictionary<string, object>> BindActionArgumentsAsync(
     ActionContext context,
     ActionBindingContext bindingContext)
 {
     return Task.FromResult<IDictionary<string, object>>(
         new Dictionary<string, object>(StringComparer.Ordinal));
 }
예제 #9
0
        private static HtmlHelper <TModel> GetHtmlHelper <TModel>(
            ViewDataDictionary <TModel> viewData,
            IUrlHelper urlHelper,
            ICompositeViewEngine viewEngine,
            IModelMetadataProvider provider,
            Func <IHtmlHelper, IHtmlHelper> innerHelperWrapper)
        {
            var httpContext = new Mock <HttpContext>();

            httpContext
            .Setup(o => o.Response)
            .Returns(Mock.Of <HttpResponse>());
            httpContext
            .Setup(o => o.Items)
            .Returns(new Dictionary <object, object>());

            var actionContext = new ActionContext(httpContext.Object,
                                                  new RouteData(),
                                                  new ActionDescriptor());

            var actionBindingContext = new ActionBindingContext(actionContext,
                                                                provider,
                                                                Mock.Of <IModelBinder>(),
                                                                Mock.Of <IValueProvider>(),
                                                                Mock.Of <IInputFormatterSelector>(),
                                                                new DataAnnotationsModelValidatorProvider());
            var actionBindingContextProvider = new Mock <IActionBindingContextProvider>();

            actionBindingContextProvider
            .Setup(c => c.GetActionBindingContextAsync(It.IsAny <ActionContext>()))
            .Returns(Task.FromResult(actionBindingContext));

            var serviceProvider = new Mock <IServiceProvider>();

            serviceProvider
            .Setup(s => s.GetService(typeof(ICompositeViewEngine)))
            .Returns(viewEngine);
            serviceProvider
            .Setup(s => s.GetService(typeof(IUrlHelper)))
            .Returns(urlHelper);
            serviceProvider
            .Setup(s => s.GetService(typeof(IViewComponentHelper)))
            .Returns(new Mock <IViewComponentHelper>().Object);

            httpContext
            .Setup(o => o.RequestServices)
            .Returns(serviceProvider.Object);

            var htmlGenerator = new DefaultHtmlGenerator(
                actionBindingContextProvider.Object,
                GetAntiForgeryInstance(),
                provider,
                urlHelper);

            // TemplateRenderer will Contextualize this transient service.
            var innerHelper = (IHtmlHelper) new HtmlHelper(htmlGenerator, viewEngine, provider);

            if (innerHelperWrapper != null)
            {
                innerHelper = innerHelperWrapper(innerHelper);
            }
            serviceProvider
            .Setup(s => s.GetService(typeof(IHtmlHelper)))
            .Returns(() => innerHelper);

            var htmlHelper  = new HtmlHelper <TModel>(htmlGenerator, viewEngine, provider);
            var viewContext = new ViewContext(actionContext, Mock.Of <IView>(), viewData, new StringWriter());

            htmlHelper.Contextualize(viewContext);

            return(htmlHelper);
        }
예제 #10
0
 protected abstract Task <IDictionary <string, object> > BindActionArgumentsAsync(
     [NotNull] ActionContext context,
     [NotNull] ActionBindingContext bindingContext);
예제 #11
0
        public async Task TryUpdateModel_UsesModelValueProviderIfSpecified()
        {
            var metadataProvider = new DataAnnotationsModelMetadataProvider();
            var valueProvider = Mock.Of<IValueProvider>();
            var binder = new Mock<IModelBinder>();
            var modelName = "mymodel";
            binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
                  .Callback((ModelBindingContext b) =>
                  {
                      Assert.Equal(modelName, b.ModelName);
                      Assert.Same(valueProvider, b.ValueProvider);
                  })
                  .Returns(Task.FromResult(false))
                  .Verifiable();
            var model = new MyModel();
            var actionContext = new ActionContext(Mock.Of<HttpContext>(), new RouteData(), new ActionDescriptor());
            var bindingContext = new ActionBindingContext(actionContext,
                                                          metadataProvider,
                                                          binder.Object,
                                                          Mock.Of<IValueProvider>(),
                                                          Mock.Of<IInputFormatterProvider>(),
                                                          Enumerable.Empty<IModelValidatorProvider>());
            var bindingContextProvider = new Mock<IActionBindingContextProvider>();
            bindingContextProvider.Setup(b => b.GetActionBindingContextAsync(actionContext))
                                  .Returns(Task.FromResult(bindingContext));
            var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary());
            var controller = new Controller
            {
                ActionContext = actionContext,
                BindingContextProvider = bindingContextProvider.Object,
                ViewData = viewData
            };

            // Act
            var result = await controller.TryUpdateModelAsync(model, modelName, valueProvider);

            // Assert
            binder.Verify();
        }
예제 #12
0
        protected override Task<IDictionary<string, object>> BindActionArgumentsAsync(
            ActionContext context,
            ActionBindingContext bindingContext)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

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

            return _argumentBinder.BindActionArgumentsAsync(context, bindingContext, Instance);
        }
예제 #13
0
        private static TestObjectResultExecutor CreateExecutor(
            IOptions<MvcOptions> options = null,
            ActionBindingContext bindingContext = null)
        {
            var bindingContextAccessor = new ActionBindingContextAccessor();
            if (bindingContext != null)
            {
                bindingContextAccessor.ActionBindingContext = bindingContext;
            }

            return new TestObjectResultExecutor(
                options ?? new TestOptionsManager<MvcOptions>(),
                bindingContextAccessor,
                new TestHttpResponseStreamWriterFactory(),
                NullLoggerFactory.Instance);
        }
예제 #14
0
        public async Task ExecuteAsync_FallsBackOnFormattersInBindingContext()
        {
            // Arrange
            var bindingContext = new ActionBindingContext()
            {
                OutputFormatters = new List<IOutputFormatter>()
                {
                    new TestJsonOutputFormatter(),
                }
            };

            var executor = CreateExecutor(bindingContext: bindingContext);

            var actionContext = new ActionContext()
            {
                HttpContext = GetHttpContext(),
            };

            var result = new ObjectResult("someValue");

            // Act
            await executor.ExecuteAsync(actionContext, result);

            // Assert
            Assert.Equal(
                "application/json; charset=utf-8",
                actionContext.HttpContext.Response.Headers[HeaderNames.ContentType]);
        }