public void ProcessDto_BindRequiredFieldMissing_Throws() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); ControllerContext controllerContext = new ControllerContext(); ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act & assert Assert.Throws <InvalidOperationException>( delegate { testableBinder.ProcessDto(controllerContext, bindingContext, dto); }, @"A value for 'theModel.Age' is required but was not present in the request."); Assert.Equal("original value", model.Name); Assert.Equal(-20, model.Age); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act & assert testableBinder.ProcessDto(context, bindingContext, dto); Assert.False(bindingContext.ModelState.IsValid); }
public void ProcessDto_BindRequiredFieldNull_RaisesModelError() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext() { ModelMetadata = containerMetadata, ModelName = "theModel", ModelState = context.ModelState, }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); ModelMetadata propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[propertyMetadata] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(propertyMetadata, "theModel.Name")); // Attempt to set non-Nullable property to null. HttpBindRequiredAttribute should not be relevant in this // case because the binding exists. propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Age"); dto.Results[propertyMetadata] = new ComplexModelDtoResult(null, new ModelValidationNode(propertyMetadata, "theModel.Age")); // Act; must also Validate because null-check error handler is late-bound testableBinder.ProcessDto(context, bindingContext, dto); bindingContext.ValidationNode.Validate(context); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); ModelError modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto( containerMetadata, containerMetadata.Properties ); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult( "John Doe", new ModelValidationNode(nameProperty, "") ); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(context, bindingContext, dto); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Single(modelStateDictionary); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); ModelError modelError = Assert.Single(modelState.Errors); Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The Age property is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForObject(model); var bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel", ValidatorProvider = Mock.Of <IModelValidatorProvider>() }; var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); var testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(bindingContext, dto); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.Equal(false, modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); var modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The 'Age' property is required.", modelError.ErrorMessage); }
public void ProcessResults_ValueTypePropertyWithBindRequired_SetToNull_CapturesException() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForType(model.GetType()); var bindingContext = new ModelBindingContext() { Model = model, ModelMetadata = containerMetadata, ModelName = "theModel", ModelState = new ModelStateDictionary(), OperationBindingContext = new OperationBindingContext { MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of<IModelValidatorProvider>() } }; var results = containerMetadata.Properties.ToDictionary( property => property, property => new ModelBindingResult(model: null, key: property.PropertyName, isModelSet: false)); var propertyMetadata = containerMetadata.Properties[nameof(model.Name)]; results[propertyMetadata] = new ModelBindingResult("John Doe", isModelSet: true, key: "theModel.Name"); // Attempt to set non-Nullable property to null. BindRequiredAttribute should not be relevant in this // case because the binding exists. propertyMetadata = containerMetadata.Properties[nameof(model.Age)]; results[propertyMetadata] = new ModelBindingResult(model: null, isModelSet: true, key: "theModel.Age"); var testableBinder = new TestableMutableObjectModelBinder(); var modelValidationNode = new ModelValidationNode(string.Empty, containerMetadata, model); // Act testableBinder.ProcessResults(bindingContext, results, modelValidationNode); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(ModelValidationState.Invalid, modelState.ValidationState); var modelError = Assert.Single(modelState.Errors); Assert.Equal(string.Empty, modelError.ErrorMessage); Assert.IsType<NullReferenceException>(modelError.Exception); }
public void ProcessResults_BindRequiredFieldMissing_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForType(model.GetType()); var bindingContext = new ModelBindingContext { Model = model, ModelMetadata = containerMetadata, ModelName = "theModel", OperationBindingContext = new OperationBindingContext { MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of<IModelValidatorProvider>() } }; var results = containerMetadata.Properties.ToDictionary( property => property, property => new ModelBindingResult(model: null, key: property.PropertyName, isModelSet: false)); var nameProperty = containerMetadata.Properties[nameof(model.Name)]; results[nameProperty] = new ModelBindingResult("John Doe", isModelSet: true, key: string.Empty); var modelValidationNode = new ModelValidationNode(string.Empty, containerMetadata, model); var testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessResults(bindingContext, results, modelValidationNode); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Single(modelStateDictionary); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); var modelError = Assert.Single(modelState.Errors); Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value for the 'Age' property was not provided.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_Throws() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); ControllerContext controllerContext = new ControllerContext(); ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act & assert Assert.Throws<InvalidOperationException>( delegate { testableBinder.ProcessDto(controllerContext, bindingContext, dto); }, @"A value for 'theModel.Age' is required but was not present in the request."); Assert.Equal("original value", model.Name); Assert.Equal(-20, model.Age); }
public async Task BindModelAsync_ValueTypePropertyWithBindRequired_SetToNull_CapturesException() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model); var binder = CreateBinder(bindingContext.ModelMetadata); // Attempt to set non-Nullable property to null. BindRequiredAttribute should not be relevant in this // case because the property did have a result. var property = GetMetadataForProperty(model.GetType(), nameof(ModelWithBindRequired.Age)); binder.Results[property] = ModelBindingResult.Success(model: null); // Act await binder.BindModelAsync(bindingContext); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelStateEntry entry; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out entry)); Assert.Equal(ModelValidationState.Invalid, entry.ValidationState); var modelError = Assert.Single(entry.Errors); Assert.Equal(string.Empty, modelError.ErrorMessage); Assert.IsType<NullReferenceException>(modelError.Exception); }
public async Task BindModelAsync_BindRequiredFieldMissing_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var property = GetMetadataForProperty(model.GetType(), nameof(ModelWithBindRequired.Age)); var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model); var binder = CreateBinder(bindingContext.ModelMetadata); binder.Results[property] = ModelBindingResult.Failed(); // Act await binder.BindModelAsync(bindingContext); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Single(modelStateDictionary); // Check Age error. ModelStateEntry entry; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out entry)); var modelError = Assert.Single(entry.Errors); Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value for the 'Age' property was not provided.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldNull_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForObject(model); var bindingContext = new ModelBindingContext() { ModelMetadata = containerMetadata, ModelName = "theModel", ModelState = new ModelStateDictionary(), ValidatorProviders = Enumerable.Empty<IModelValidatorProvider>() }; var validationContext = new ModelValidationContext(new EmptyModelMetadataProvider(), bindingContext.ValidatorProviders, bindingContext.ModelState, containerMetadata, null); var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var testableBinder = new TestableMutableObjectModelBinder(); var propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[propertyMetadata] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(propertyMetadata, "theModel.Name")); // Attempt to set non-Nullable property to null. BindRequiredAttribute should not be relevant in this // case because the binding exists. propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Age"); dto.Results[propertyMetadata] = new ComplexModelDtoResult(null, new ModelValidationNode(propertyMetadata, "theModel.Age")); // Act; must also Validate because null-check error handler is late-bound testableBinder.ProcessDto(bindingContext, dto); bindingContext.ValidationNode.Validate(validationContext); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.Equal(false, modelStateDictionary.IsValid); Assert.Equal(2, modelStateDictionary.Count); // Check Name field ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Name", out modelState)); Assert.Equal(0, modelState.Errors.Count); Assert.Equal(ModelValidationState.Valid, modelState.ValidationState); // Check Age error. Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); Assert.Equal(ModelValidationState.Invalid, modelState.ValidationState); var modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForObject(model); var bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel", ValidatorProviders = Enumerable.Empty<IModelValidatorProvider>() }; var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); var testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(bindingContext, dto); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.Equal(false, modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); var modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The 'Age' property is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForType(model.GetType()); var bindingContext = new ModelBindingContext { Model = model, ModelMetadata = containerMetadata, ModelName = "theModel", OperationBindingContext = new OperationBindingContext { MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of<IModelValidatorProvider>() } }; var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ModelBindingResult( "John Doe", isModelSet: true, key: ""); var modelValidationNode = new ModelValidationNode(string.Empty, containerMetadata, model); var testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(bindingContext, dto, modelValidationNode); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Single(modelStateDictionary); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); var modelError = Assert.Single(modelState.Errors); Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The 'Age' property is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(context, bindingContext, dto); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); ModelError modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The Age property is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldNull_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForObject(model); var bindingContext = new ModelBindingContext() { ModelMetadata = containerMetadata, ModelName = "theModel", ModelState = new ModelStateDictionary(), ValidatorProvider = Mock.Of <IModelValidatorProvider>() }; var validationContext = new ModelValidationContext(new EmptyModelMetadataProvider(), bindingContext.ValidatorProvider, bindingContext.ModelState, containerMetadata, null); var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var testableBinder = new TestableMutableObjectModelBinder(); var propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[propertyMetadata] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(propertyMetadata, "theModel.Name")); // Attempt to set non-Nullable property to null. BindRequiredAttribute should not be relevant in this // case because the binding exists. propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Age"); dto.Results[propertyMetadata] = new ComplexModelDtoResult(null, new ModelValidationNode(propertyMetadata, "theModel.Age")); // Act; must also Validate because null-check error handler is late-bound testableBinder.ProcessDto(bindingContext, dto); bindingContext.ValidationNode.Validate(validationContext); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.Equal(false, modelStateDictionary.IsValid); Assert.Equal(2, modelStateDictionary.Count); // Check Name field ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Name", out modelState)); Assert.Equal(0, modelState.Errors.Count); Assert.Equal(ModelValidationState.Valid, modelState.ValidationState); // Check Age error. Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); Assert.Equal(ModelValidationState.Invalid, modelState.ValidationState); var modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldNull_RaisesModelError() { // Arrange var model = new ModelWithBindRequired { Name = "original value", Age = -20 }; var containerMetadata = GetMetadataForType(model.GetType()); var bindingContext = new ModelBindingContext() { Model = model, ModelMetadata = containerMetadata, ModelName = "theModel", ModelState = new ModelStateDictionary(), OperationBindingContext = new OperationBindingContext { MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of<IModelValidatorProvider>() } }; var dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); var testableBinder = new TestableMutableObjectModelBinder(); var propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[propertyMetadata] = new ModelBindingResult( "John Doe", isModelSet: true, key: "theModel.Name"); // Attempt to set non-Nullable property to null. BindRequiredAttribute should not be relevant in this // case because the binding exists. propertyMetadata = dto.PropertyMetadata.Single(o => o.PropertyName == "Age"); dto.Results[propertyMetadata] = new ModelBindingResult( null, isModelSet: true, key: "theModel.Age"); // Act testableBinder.ProcessDto(bindingContext, dto); // Assert var modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(ModelValidationState.Invalid, modelState.ValidationState); var modelError = Assert.Single(modelState.Errors); Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("A value is required.", modelError.ErrorMessage); }