public async Task BindModelAsync_PassesExpectedBindingInfoAndMetadata_IfPrefixDoesNotMatch( BindingInfo parameterBindingInfo, string metadataBinderModelName, string parameterName, string expectedModelName) { // Arrange var binderExecuted = false; var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType <Person>().BindingDetails(binding => { binding.BinderModelName = metadataBinderModelName; }); var metadata = metadataProvider.GetMetadataForType(typeof(Person)); var modelBinder = new Mock <IModelBinder>(); modelBinder .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>())) .Callback((ModelBindingContext context) => { Assert.Equal(expectedModelName, context.ModelName, StringComparer.Ordinal); }) .Returns(Task.CompletedTask); var parameterDescriptor = new ParameterDescriptor { BindingInfo = parameterBindingInfo, Name = parameterName, ParameterType = typeof(Person), }; var factory = new Mock <IModelBinderFactory>(MockBehavior.Strict); factory .Setup(f => f.CreateBinder(It.IsAny <ModelBinderFactoryContext>())) .Callback((ModelBinderFactoryContext context) => { binderExecuted = true; // Confirm expected data is passed through to ModelBindingFactory. Assert.Same(parameterDescriptor.BindingInfo, context.BindingInfo); Assert.Same(parameterDescriptor, context.CacheToken); Assert.Equal(metadata, context.Metadata); }) .Returns(modelBinder.Object); var parameterBinder = new ParameterBinder( metadataProvider, factory.Object, CreateMockValidatorProvider(), NullLoggerFactory.Instance); var controllerContext = GetControllerContext(); // Act & Assert await parameterBinder.BindModelAsync(controllerContext, new SimpleValueProvider(), parameterDescriptor); Assert.True(binderExecuted); }
public void EnterNestedScope_FiltersValueProviders_BasedOnTopLevelValueProviders() { // Arrange var metadataProvider = new TestModelMetadataProvider(); metadataProvider .ForProperty(typeof(string), nameof(string.Length)) .BindingDetails(b => b.BindingSource = BindingSource.Form); var original = CreateDefaultValueProvider(); var operationBindingContext = new OperationBindingContext() { ActionContext = new ActionContext(), ValueProvider = original, }; var context = DefaultModelBindingContext.CreateBindingContext( operationBindingContext, metadataProvider.GetMetadataForType(typeof(string)), new BindingInfo() { BindingSource = BindingSource.Query }, "model"); var propertyMetadata = metadataProvider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act context.EnterNestedScope(propertyMetadata, "Length", "Length", model: null); // Assert Assert.Collection( Assert.IsType <CompositeValueProvider>(context.ValueProvider), vp => Assert.Same(original[2], vp)); }
public void CreateBinder_Caches_WhenTokenIsNotNull() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = new TestOptionsManager <MvcOptions>(); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c => { Assert.Equal(typeof(Employee), c.Metadata.ModelType); return(Mock.Of <IModelBinder>()); })); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Employee)), CacheToken = new object(), }; // Act var result1 = factory.CreateBinder(context); var result2 = factory.CreateBinder(context); // Assert Assert.Same(result1, result2); }
public void CreateBindingContext_FiltersValueProviders_ForValueProviderSource() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var original = CreateDefaultValueProvider(); var operationBindingContext = new OperationBindingContext() { ActionContext = new ActionContext(), ValueProvider = original, }; // Act var context = DefaultModelBindingContext.CreateBindingContext( operationBindingContext, metadataProvider.GetMetadataForType(typeof(object)), new BindingInfo() { BindingSource = BindingSource.Query }, "model"); // Assert Assert.Collection( Assert.IsType <CompositeValueProvider>(context.ValueProvider), vp => Assert.Same(original[1], vp)); }
public void CreateBinder_CreatesNoOpBinder_WhenPropertyDoesntHaveABinder() { // Arrange var metadataProvider = new TestModelMetadataProvider(); // There isn't a provider that can handle WidgetId. var options = new TestOptionsManager <MvcOptions>(); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c => { if (c.Metadata.ModelType == typeof(Widget)) { Assert.NotNull(c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)])); return(Mock.Of <IModelBinder>()); } return(null); })); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Widget)), }; // Act var result = factory.CreateBinder(context); // Assert Assert.NotNull(result); }
public void CreateBinder_DoesNotCache_WhenTokenIsNull() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c => { Assert.Equal(typeof(Employee), c.Metadata.ModelType); return(Mock.Of <IModelBinder>()); })); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Employee)), }; // Act var result1 = factory.CreateBinder(context); var result2 = factory.CreateBinder(context); // Assert Assert.NotSame(result1, result2); }
public void CreateBinder_NestedProperties() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c => { if (c.Metadata.ModelType == typeof(Widget)) { Assert.NotNull(c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)])); return(Mock.Of <IModelBinder>()); } else if (c.Metadata.ModelType == typeof(WidgetId)) { return(Mock.Of <IModelBinder>()); } return(null); })); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Widget)), }; // Act var result = factory.CreateBinder(context); // Assert Assert.NotNull(result); }
public void GetBindingInfo_WithAttributesAndModelMetadata_UsesValuesFromBindingInfo_IfAttributesPresent() { // Arrange var attributes = new object[] { new ModelBinderAttribute { BinderType = typeof(ComplexTypeModelBinder), Name = "Test" }, }; var modelType = typeof(Guid); var provider = new TestModelMetadataProvider(); provider.ForType(modelType).BindingDetails(metadata => { metadata.BindingSource = BindingSource.Special; metadata.BinderType = typeof(SimpleTypeModelBinder); metadata.BinderModelName = "Different"; }); var modelMetadata = provider.GetMetadataForType(modelType); // Act var bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata); // Assert Assert.NotNull(bindingInfo); Assert.Same(typeof(ComplexTypeModelBinder), bindingInfo.BinderType); Assert.Same("Test", bindingInfo.BinderModelName); }
public void GetBindingInfo_WithAttributesAndModelMetadata_UsesPropertyPredicateProviderFromModelMetadata_WhenNotFoundViaAttributes() { // Arrange var attributes = new object[] { new ModelBinderAttribute(typeof(ComplexTypeModelBinder)), new ControllerAttribute(), new BindNeverAttribute(), }; var propertyFilterProvider = Mock.Of <IPropertyFilterProvider>(); var modelType = typeof(Guid); var provider = new TestModelMetadataProvider(); provider.ForType(modelType).BindingDetails(metadata => { metadata.PropertyFilterProvider = propertyFilterProvider; }); var modelMetadata = provider.GetMetadataForType(modelType); // Act var bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata); // Assert Assert.NotNull(bindingInfo); Assert.Same(propertyFilterProvider, bindingInfo.PropertyFilterProvider); }
public void GetBindingInfo_WithAttributesAndModelMetadata_UsesBinderSourceFromModelMetadata_WhenNotFoundViaAttributes() { // Arrange var attributes = new object[] { new BindPropertyAttribute(), new ControllerAttribute(), new BindNeverAttribute(), }; var modelType = typeof(Guid); var provider = new TestModelMetadataProvider(); provider.ForType(modelType).BindingDetails(metadata => { metadata.BindingSource = BindingSource.Services; }); var modelMetadata = provider.GetMetadataForType(modelType); // Act var bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata); // Assert Assert.NotNull(bindingInfo); Assert.Same(BindingSource.Services, bindingInfo.BindingSource); }
public void GetBindingInfo_WithAttributesAndModelMetadata_UsesBinderNameFromModelMetadata_WhenNotFoundViaAttributes() { // Arrange var attributes = new object[] { new ModelBinderAttribute(typeof(ComplexTypeModelBinder)), new ControllerAttribute(), new BindNeverAttribute(), }; var modelType = typeof(Guid); var provider = new TestModelMetadataProvider(); provider.ForType(modelType).BindingDetails(metadata => { metadata.BindingSource = BindingSource.Special; metadata.BinderType = typeof(SimpleTypeModelBinder); metadata.BinderModelName = "Different"; }); var modelMetadata = provider.GetMetadataForType(modelType); // Act var bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata); // Assert Assert.NotNull(bindingInfo); Assert.Same(typeof(ComplexTypeModelBinder), bindingInfo.BinderType); Assert.Same("Different", bindingInfo.BinderModelName); Assert.Same(BindingSource.Custom, bindingInfo.BindingSource); }
public async Task ObsoleteBindModelAsync_PassesExpectedBindingInfoAndMetadata_IfPrefixMatches() { // Arrange var expectedModelName = "expectedName"; var binderExecuted = false; var metadataProvider = new TestModelMetadataProvider(); var metadata = metadataProvider.GetMetadataForType(typeof(Person)); var modelBinder = new Mock <IModelBinder>(); modelBinder .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>())) .Callback((ModelBindingContext context) => { Assert.Equal(expectedModelName, context.ModelName, StringComparer.Ordinal); }) .Returns(Task.CompletedTask); var parameterDescriptor = new ParameterDescriptor { Name = expectedModelName, ParameterType = typeof(Person), }; var factory = new Mock <IModelBinderFactory>(MockBehavior.Strict); factory .Setup(f => f.CreateBinder(It.IsAny <ModelBinderFactoryContext>())) .Callback((ModelBinderFactoryContext context) => { binderExecuted = true; // Confirm expected data is passed through to ModelBindingFactory. Assert.Null(context.BindingInfo); Assert.Same(parameterDescriptor, context.CacheToken); Assert.Equal(metadata, context.Metadata); }) .Returns(modelBinder.Object); var argumentBinder = new ParameterBinder( metadataProvider, factory.Object, Mock.Of <IObjectModelValidator>(), _optionsAccessor, NullLoggerFactory.Instance); var valueProvider = new SimpleValueProvider { { expectedModelName, new object() }, }; var valueProviderFactory = new SimpleValueProviderFactory(valueProvider); var controllerContext = GetControllerContext(); // Act & Assert #pragma warning disable CS0618 // Type or member is obsolete await argumentBinder.BindModelAsync(controllerContext, valueProvider, parameterDescriptor); #pragma warning restore CS0618 // Type or member is obsolete Assert.True(binderExecuted); }
public void CreateBinder_Caches_NonRootNodes_WhenNonRootNodeReturnsNull() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); IModelBinder inner = null; var widgetProvider = new TestModelBinderProvider(c => { if (c.Metadata.ModelType == typeof(Widget)) { var binder = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]); Assert.IsType <NoOpBinder>(binder); if (inner == null) { inner = binder; } else { Assert.Same(inner, binder); } return(Mock.Of <IModelBinder>()); } return(null); }); var widgetIdProvider = new TestModelBinderProvider(c => { Assert.Equal(typeof(WidgetId), c.Metadata.ModelType); return(null); }); options.Value.ModelBinderProviders.Add(widgetProvider); options.Value.ModelBinderProviders.Add(widgetIdProvider); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Widget)), CacheToken = null, // We want the outermost provider to run twice. }; // Act var result1 = factory.CreateBinder(context); var result2 = factory.CreateBinder(context); // Assert Assert.NotSame(result1, result2); Assert.Equal(2, widgetProvider.SuccessCount); Assert.Equal(0, widgetIdProvider.SuccessCount); }
public void CreateBinder_Caches_NonRootNodes_FixesUpPlaceholderBinder() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = new TestOptionsManager <MvcOptions>(); IModelBinder inner = null; IModelBinder innerInner = null; var widgetProvider = new TestModelBinderProvider(c => { if (c.Metadata.ModelType == typeof(Widget)) { inner = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]); return(Mock.Of <IModelBinder>()); } return(null); }); var widgetIdProvider = new TestModelBinderProvider(c => { Assert.Equal(typeof(WidgetId), c.Metadata.ModelType); innerInner = c.CreateBinder(c.Metadata); return(null); }); options.Value.ModelBinderProviders.Add(widgetProvider); options.Value.ModelBinderProviders.Add(widgetIdProvider); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Widget)), CacheToken = null, }; // Act 1 var result1 = factory.CreateBinder(context); context.Metadata = context.Metadata.Properties[nameof(Widget.Id)]; context.CacheToken = context.Metadata; // Act 2 var result2 = factory.CreateBinder(context); // Assert Assert.Same(inner, result2); Assert.NotSame(inner, innerInner); var placeholder = Assert.IsType <PlaceholderBinder>(innerInner); Assert.IsType <NoOpBinder>(placeholder.Inner); Assert.Equal(1, widgetProvider.SuccessCount); Assert.Equal(0, widgetIdProvider.SuccessCount); }
public async Task BindModelAsync_ForOverlappingParametersWithSuppressions_InValid_WithValidSecondParameter() { // Arrange var parameterDescriptor = new ParameterDescriptor { Name = "patchDocument", ParameterType = typeof(IJsonPatchDocument), }; var actionContext = GetControllerContext(); var modelState = actionContext.ModelState; // First ModelState key is not empty to match SimpleTypeModelBinder. modelState.SetModelValue("id", "notAGuid", "notAGuid"); modelState.AddModelError("id", "This is not valid."); var modelMetadataProvider = new TestModelMetadataProvider(); modelMetadataProvider.ForType <IJsonPatchDocument>().ValidationDetails(v => v.ValidateChildren = false); var modelMetadata = modelMetadataProvider.GetMetadataForType(typeof(IJsonPatchDocument)); var parameterBinder = new ParameterBinder( modelMetadataProvider, Mock.Of <IModelBinderFactory>(), new DefaultObjectValidator( modelMetadataProvider, new[] { TestModelValidatorProvider.CreateDefaultProvider() }, new MvcOptions()), _optionsAccessor, NullLoggerFactory.Instance); // BodyModelBinder does not update ModelState in success case. var modelBindingResult = ModelBindingResult.Success(new JsonPatchDocument()); var modelBinder = CreateMockModelBinder(modelBindingResult); // Act var result = await parameterBinder.BindModelAsync( actionContext, modelBinder, new SimpleValueProvider(), parameterDescriptor, modelMetadata, value : null); // Assert Assert.True(result.IsModelSet); Assert.False(modelState.IsValid); Assert.Collection( modelState, kvp => { Assert.Equal("id", kvp.Key); Assert.Equal(ModelValidationState.Invalid, kvp.Value.ValidationState); var error = Assert.Single(kvp.Value.Errors); Assert.Equal("This is not valid.", error.ErrorMessage); }); }
public void CreateBinder_Caches_NonRootNodes_UsesModelMetadataAsToken() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); IModelBinder inner = null; var widgetProvider = new TestModelBinderProvider(c => { if (c.Metadata.ModelType == typeof(Widget)) { inner = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]); return(Mock.Of <IModelBinder>()); } return(null); }); var widgetIdProvider = new TestModelBinderProvider(c => { Assert.Equal(typeof(WidgetId), c.Metadata.ModelType); return(Mock.Of <IModelBinder>()); }); options.Value.ModelBinderProviders.Add(widgetProvider); options.Value.ModelBinderProviders.Add(widgetIdProvider); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Widget)), CacheToken = null, }; // Act 1 var result1 = factory.CreateBinder(context); context.Metadata = context.Metadata.Properties[nameof(Widget.Id)]; context.CacheToken = context.Metadata; // Act 2 var result2 = factory.CreateBinder(context); // Assert Assert.Same(inner, result2); Assert.Equal(1, widgetProvider.SuccessCount); Assert.Equal(1, widgetIdProvider.SuccessCount); }
public void EnterNestedScope_CopiesProperties() { // Arrange var bindingContext = new DefaultModelBindingContext { Model = new object(), ModelMetadata = new TestModelMetadataProvider().GetMetadataForType(typeof(object)), ModelName = "theName", OperationBindingContext = new OperationBindingContext(), ValueProvider = new SimpleValueProvider(), ModelState = new ModelStateDictionary(), }; var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType <object>().BindingDetails(d => { d.BindingSource = BindingSource.Custom; d.BinderType = typeof(TestModelBinder); d.BinderModelName = "custom"; }); var newModelMetadata = metadataProvider.GetMetadataForType(typeof(object)); // Act var originalBinderModelName = bindingContext.BinderModelName; var originalBinderType = bindingContext.BinderType; var originalBindingSource = bindingContext.BindingSource; var originalModelState = bindingContext.ModelState; var originalOperationBindingContext = bindingContext.OperationBindingContext; var originalValueProvider = bindingContext.ValueProvider; var disposable = bindingContext.EnterNestedScope( modelMetadata: newModelMetadata, fieldName: "fieldName", modelName: "modelprefix.fieldName", model: null); // Assert Assert.Same(newModelMetadata.BinderModelName, bindingContext.BinderModelName); Assert.Same(newModelMetadata.BinderType, bindingContext.BinderType); Assert.Same(newModelMetadata.BindingSource, bindingContext.BindingSource); Assert.False(bindingContext.FallbackToEmptyPrefix); Assert.Equal("fieldName", bindingContext.FieldName); Assert.False(bindingContext.IsTopLevelObject); Assert.Null(bindingContext.Model); Assert.Same(newModelMetadata, bindingContext.ModelMetadata); Assert.Equal("modelprefix.fieldName", bindingContext.ModelName); Assert.Same(originalModelState, bindingContext.ModelState); Assert.Same(originalOperationBindingContext, bindingContext.OperationBindingContext); Assert.Same(originalValueProvider, bindingContext.ValueProvider); disposable.Dispose(); }
public async Task BindModelAsync_ForOverlappingParameters_InValid_WithInValidFirstParameterAndSecondNull() { // Arrange var parameterDescriptor = new ParameterDescriptor { BindingInfo = new BindingInfo { BinderModelName = "id", }, Name = "identifier", ParameterType = typeof(string), }; var actionContext = GetControllerContext(); var modelState = actionContext.ModelState; // Mimic ModelStateEntry when first parameter is [FromRoute] int id and request URI is /api/values/notAnInt modelState.SetModelValue("id", "notAnInt", "notAnInt"); modelState.AddModelError("id", "This is not valid."); var modelMetadataProvider = new TestModelMetadataProvider(); var modelMetadata = modelMetadataProvider.GetMetadataForType(typeof(string)); var parameterBinder = new ParameterBinder( modelMetadataProvider, Mock.Of <IModelBinderFactory>(), new DefaultObjectValidator( modelMetadataProvider, new[] { TestModelValidatorProvider.CreateDefaultProvider() }, new MvcOptions()), _optionsAccessor, NullLoggerFactory.Instance); // Mimic result when second parameter is [FromQuery(Name = "id")] string identifier and query is ?id var modelBindingResult = ModelBindingResult.Success(null); var modelBinder = CreateMockModelBinder(modelBindingResult); // Act var result = await parameterBinder.BindModelAsync( actionContext, modelBinder, new SimpleValueProvider(), parameterDescriptor, modelMetadata, value : null); // Assert Assert.True(result.IsModelSet); Assert.False(modelState.IsValid); var keyValuePair = Assert.Single(modelState); Assert.Equal("id", keyValuePair.Key); Assert.Equal(ModelValidationState.Invalid, keyValuePair.Value.ValidationState); }
public TestModelBinderProviderContext(Type modelType) { Metadata = CachedMetadataProvider.GetMetadataForType(modelType); MetadataProvider = CachedMetadataProvider; BindingInfo = new BindingInfo() { BinderModelName = Metadata.BinderModelName, BinderType = Metadata.BinderType, BindingSource = Metadata.BindingSource, PropertyFilterProvider = Metadata.PropertyFilterProvider, }; }
public void CreateBinder_PassesExpectedBindingInfo( BindingInfo parameterBindingInfo, BindingMetadata bindingMetadata, BindingInfo expectedInfo) { // Arrange var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType <Employee>().BindingDetails(binding => { binding.BinderModelName = bindingMetadata.BinderModelName; binding.BinderType = bindingMetadata.BinderType; binding.BindingSource = bindingMetadata.BindingSource; if (bindingMetadata.PropertyFilterProvider != null) { binding.PropertyFilterProvider = bindingMetadata.PropertyFilterProvider; } }); var modelBinder = Mock.Of <IModelBinder>(); var modelBinderProvider = new TestModelBinderProvider(context => { Assert.Equal(typeof(Employee), context.Metadata.ModelType); Assert.NotNull(context.BindingInfo); Assert.Equal(expectedInfo.BinderModelName, context.BindingInfo.BinderModelName, StringComparer.Ordinal); Assert.Equal(expectedInfo.BinderType, context.BindingInfo.BinderType); Assert.Equal(expectedInfo.BindingSource, context.BindingInfo.BindingSource); Assert.Same(expectedInfo.PropertyFilterProvider, context.BindingInfo.PropertyFilterProvider); return(modelBinder); }); var options = Options.Create(new MvcOptions()); options.Value.ModelBinderProviders.Insert(0, modelBinderProvider); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var factoryContext = new ModelBinderFactoryContext { BindingInfo = parameterBindingInfo, Metadata = metadataProvider.GetMetadataForType(typeof(Employee)), }; // Act & Assert var result = factory.CreateBinder(factoryContext); // Confirm our IModelBinderProvider was called. Assert.Same(modelBinder, result); }
public TestModelBinderProviderContext(Type modelType, BindingInfo bindingInfo) { Metadata = CachedMetadataProvider.GetMetadataForType(modelType); MetadataProvider = CachedMetadataProvider; _bindingInfo = bindingInfo ?? new BindingInfo { BinderModelName = Metadata.BinderModelName, BinderType = Metadata.BinderType, BindingSource = Metadata.BindingSource, PropertyFilterProvider = Metadata.PropertyFilterProvider, }; Services = GetServices(); }
public void CreateBinder_Throws_WhenNoProviders() { // Arrange var expected = $"'{typeof(MvcOptions).FullName}.{nameof(MvcOptions.ModelBinderProviders)}' must not be " + $"empty. At least one '{typeof(IModelBinderProvider).FullName}' is required to model bind."; var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(string)), }; // Act & Assert var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateBinder(context)); Assert.Equal(expected, exception.Message); }
public void CreateBinder_Throws_WhenBinderNotCreated() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = new TestOptionsManager <MvcOptions>(); var factory = new ModelBinderFactory(metadataProvider, options); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(string)), }; // Act var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateBinder(context)); // Assert Assert.Equal( $"Could not create a model binder for model object of type '{typeof(string).FullName}'.", exception.Message); }
public void CreateBinder_BreaksCycles() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var callCount = 0; var options = Options.Create(new MvcOptions()); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c => { var currentCallCount = ++callCount; Assert.Equal(typeof(Employee), c.Metadata.ModelType); var binder = c.CreateBinder(c.Metadata.Properties[nameof(Employee.Manager)]); if (currentCallCount == 2) { Assert.IsType <PlaceholderBinder>(binder); } return(Mock.Of <IModelBinder>()); })); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(Employee)), }; // Act var result = factory.CreateBinder(context); // Assert Assert.NotNull(result); }
private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Services); var modelMetadata = metadataProvider.GetMetadataForType(modelType); var services = new ServiceCollection(); services.AddSingleton <IService>(new Service()); var bindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ModelName = "modelName", FieldName = "modelName", ModelState = new ModelStateDictionary(), OperationBindingContext = new OperationBindingContext { ActionContext = new ActionContext() { HttpContext = new DefaultHttpContext() { RequestServices = services.BuildServiceProvider(), } }, ModelBinder = new HeaderModelBinder(), MetadataProvider = metadataProvider, }, BinderModelName = modelMetadata.BinderModelName, BindingSource = modelMetadata.BindingSource, ValidationState = new ValidationStateDictionary(), }; return(bindingContext); }
public void CreateBinder_Throws_WhenBinderNotCreated() { // Arrange var metadataProvider = new TestModelMetadataProvider(); var options = Options.Create(new MvcOptions()); options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(_ => null)); var factory = new ModelBinderFactory( metadataProvider, options, GetServices()); var context = new ModelBinderFactoryContext() { Metadata = metadataProvider.GetMetadataForType(typeof(string)), }; // Act & Assert var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateBinder(context)); Assert.Equal( $"Could not create a model binder for model object of type '{typeof(string).FullName}'.", exception.Message); }