public void SetProperty_SettingNullableTypeToNull_RequiredValidatorPresent_PropertySetterThrows_AddsRequiredMessageString() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new ModelWhosePropertySetterThrows()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "Name"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.Name"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); ModelValidator requiredValidator = context.GetValidators(propertyMetadata).Where(v => v.IsRequired).FirstOrDefault(); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(context, bindingContext, propertyMetadata, dtoResult, requiredValidator); // Assert Assert.False(bindingContext.ModelState.IsValid); Assert.Equal(1, bindingContext.ModelState["foo.Name"].Errors.Count); Assert.Equal("This message comes from the [Required] attribute.", bindingContext.ModelState["foo.Name"].Errors[0].ErrorMessage); }
internal static bool ValidateObject(object o, List <ValidationResultInfo> validationErrors, HttpActionContext actionContext) { // create a model validation node for the object ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider(); string modelStateKey = String.Empty; ModelValidationNode validationNode = CreateModelValidationNode(o, metadataProvider, actionContext.ModelState, modelStateKey); validationNode.ValidateAllProperties = true; // add the node to model state ModelState modelState = new ModelState(); modelState.Value = new ValueProviderResult(o, String.Empty, CultureInfo.CurrentCulture); actionContext.ModelState.Add(modelStateKey, modelState); // invoke validation validationNode.Validate(actionContext); if (!actionContext.ModelState.IsValid) { foreach (var modelStateItem in actionContext.ModelState) { foreach (ModelError modelError in modelStateItem.Value.Errors) { validationErrors.Add(new ValidationResultInfo(modelError.ErrorMessage, new string[] { modelStateItem.Key })); } } } return(actionContext.ModelState.IsValid); }
public void SetProperty_PropertyIsSettable_CallsSetter() { // Arrange Person model = new Person(); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(model) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode); ModelValidator requiredValidator = context.GetValidators(propertyMetadata).Where(v => v.IsRequired).FirstOrDefault(); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(context, bindingContext, propertyMetadata, dtoResult, requiredValidator); // Assert validationNode.Validate(context); Assert.True(context.ModelState.IsValid); Assert.Equal(new DateTime(2001, 1, 1), model.DateOfBirth); }
public void SetProperty_SettingNullableTypeToNull_RequiredValidatorPresent_PropertySetterThrows_AddsRequiredMessageString() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(new ModelWhosePropertySetterThrows()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "Name"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.Name"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.IsFalse(bindingContext.ModelState.IsValid, "ModelState should've been marked invalid."); Assert.AreEqual(1, bindingContext.ModelState["foo.Name"].Errors.Count); Assert.AreEqual("This message comes from the [Required] attribute.", bindingContext.ModelState["foo.Name"].Errors[0].ErrorMessage); }
public Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext.ModelType != typeof(Address)) { return(null); } var address = new Address() { Street = "SomeStreet" }; bindingContext.ModelState.SetModelValue( ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Street"), new ValueProviderResult( address.Street, address.Street, CultureInfo.CurrentCulture)); var validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, address) { ValidateAllProperties = true }; return(Task.FromResult(new ModelBindingResult(address, bindingContext.ModelName, true, validationNode))); }
public void SetProperty_PropertyIsSettable_CallsSetter() { // Arrange Person model = new Person(); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(model) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert validationNode.Validate(controllerContext); Assert.IsTrue(controllerContext.Controller.ViewData.ModelState.IsValid, "ModelState shouldn't have been touched."); Assert.AreEqual(new DateTime(2001, 1, 1), model.DateOfBirth); }
public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(new Person()), }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.IsTrue(controllerContext.Controller.ViewData.ModelState.IsValid, "ModelState shouldn't have been touched yet."); validationNode.Validate(controllerContext, bindingContext.ValidationNode); Assert.IsFalse(controllerContext.Controller.ViewData.ModelState.IsValid, "ModelState should've been marked invalid."); }
public void Validate_SkipsValidationIfSuppressed() { // Arrange List <string> log = new List <string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") { SuppressValidation = true }; node.Validating += (sender, e) => { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert Assert.Empty(log); }
public void Validate_ValidateAllProperties_AddsValidationErrors() { // Arrange ValidateAllPropertiesModel model = new ValidateAllPropertiesModel { RequiredString = null /* error */, RangedInt = 0 /* error */, ValidString = "dog" }; ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") { ValidateAllProperties = true }; controllerContext.Controller.ViewData.ModelState.AddModelError("theKey.RequiredString.Dummy", "existing Error Text"); // Act node.Validate(controllerContext); // Assert Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey.RequiredString"]); Assert.Equal("existing Error Text", controllerContext.Controller.ViewData.ModelState["theKey.RequiredString.Dummy"].Errors[0].ErrorMessage); Assert.Equal("The field RangedInt must be between 10 and 30.", controllerContext.Controller.ViewData.ModelState["theKey.RangedInt"].Errors[0].ErrorMessage); Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey.ValidString"]); Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey"]); }
public void Validate_SkipsRemainingValidationIfModelStateIsInvalid() { // Because a property validator fails, the model validator shouldn't run // Arrange List <string> log = new List <string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty")); node.Validating += delegate { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert Assert.Equal(new[] { "In OnValidating()", "In IDataErrorInfo.get_Item('InvalidStringProperty')", "In OnValidated()" }, log.ToArray()); Assert.Equal("Sample error message", controllerContext.Controller.ViewData.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage); }
public void Validate_SkipsValidationIfHandlerCancels() { // Arrange List <string> log = new List <string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); node.Validating += (sender, e) => { log.Add("In OnValidating()"); e.Cancel = true; }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert Assert.Equal(new[] { "In OnValidating()" }, log.ToArray()); }
public void Validate_PassesNullContainerInstanceIfCannotBeConvertedToProperType() { // Arrange List <string> log1 = new List <string>(); LoggingDataErrorInfoModel model1 = new LoggingDataErrorInfoModel(log1); ModelMetadata modelMetadata1 = GetModelMetadata(model1); List <string> log2 = new List <string>(); LoggingDataErrorInfoModel model2 = new LoggingDataErrorInfoModel(log2); ModelMetadata modelMetadata2 = GetModelMetadata(model2); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata1, "theKey"); node.ChildNodes.Add(new ModelValidationNode(modelMetadata2, "theKey.SomeProperty")); // Act node.Validate(controllerContext); // Assert Assert.Equal(new[] { "In IDataErrorInfo.get_Error()" }, log1.ToArray()); Assert.Equal(new[] { "In IDataErrorInfo.get_Error()" }, log2.ToArray()); }
public void Validate_Ordering() { // Proper order of invocation: // 1. OnValidating() // 2. Child validators // 3. This validator // 4. OnValidated() // Arrange List <string> log = new List <string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty")); node.Validating += delegate { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert Assert.Equal(new[] { "In OnValidating()", "In IDataErrorInfo.get_Item('ValidStringProperty')", "In IDataErrorInfo.get_Error()", "In OnValidated()" }, log.ToArray()); }
public async Task BindModel_UsesTheValidationNodeOnModelBindingResult_IfPresent() { // Arrange var valueProvider = new SimpleHttpValueProvider(); ModelValidationNode validationNode = null; var mockBinder = new Mock <IModelBinder>(); mockBinder .Setup(o => o.BindModelAsync(It.IsAny <ModelBindingContext>())) .Returns( delegate(ModelBindingContext context) { validationNode = new ModelValidationNode("someName", context.ModelMetadata, 42); return(Task.FromResult( new ModelBindingResult(42, "someName", isModelSet: true, validationNode: validationNode))); }); var binder = CreateCompositeBinder(mockBinder.Object); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act var result = await binder.BindModelAsync(bindingContext); // Assert Assert.NotNull(result); Assert.True(result.IsModelSet); Assert.Same(validationNode, result.ValidationNode); }
public void NullCheckFailedHandler_ModelStateValid_CallbackReturnsNull_DoesNothing() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(controllerContext, null /* parentNode */); // Act ModelBinderErrorMessageProvider originalProvider = ModelBinderConfig.ValueRequiredErrorMessageProvider; try { ModelBinderConfig.ValueRequiredErrorMessageProvider = delegate { return(null); }; EventHandler <ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(controllerContext, modelMetadata, null /* incomingValue */); handler(validationNode, e); } finally { ModelBinderConfig.ValueRequiredErrorMessageProvider = originalProvider; } // Assert Assert.IsTrue(controllerContext.Controller.ViewData.ModelState.IsValid, "ModelState shouldn't be marked invalid if the callback returns null."); }
public void CombineWith() { // Arrange List <string> log = new List <string>(); ModelValidationNode[] allChildNodes = new[] { new ModelValidationNode(GetModelMetadata(), "key1"), new ModelValidationNode(GetModelMetadata(), "key2"), new ModelValidationNode(GetModelMetadata(), "key3"), }; ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1"); parentNode1.ChildNodes.Add(allChildNodes[0]); parentNode1.Validating += delegate { log.Add("Validating parent1."); }; parentNode1.Validated += delegate { log.Add("Validated parent1."); }; ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2"); parentNode2.ChildNodes.Add(allChildNodes[1]); parentNode2.ChildNodes.Add(allChildNodes[2]); parentNode2.Validating += delegate { log.Add("Validating parent2."); }; parentNode2.Validated += delegate { log.Add("Validated parent2."); }; // Act parentNode1.CombineWith(parentNode2); parentNode1.Validate(new ControllerContext { Controller = new EmptyController() }); // Assert Assert.Equal(new[] { "Validating parent1.", "Validating parent2.", "Validated parent1.", "Validated parent2." }, log.ToArray()); Assert.Equal(allChildNodes, parentNode1.ChildNodes.ToArray()); }
public void SetProperty_PropertyHasDefaultValue_SetsDefaultValue() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(new Person()) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "PropertyWithDefaultValue"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.AreEqual(123.456m, ((Person)bindingContext.Model).PropertyWithDefaultValue); Assert.IsTrue(controllerContext.Controller.ViewData.ModelState.IsValid, "ModelState should be valid."); }
public void NullCheckFailedHandler_ModelStateAlreadyInvalid_DoesNothing() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); context.ModelState.AddModelError("foo.bar", "Some existing error."); ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs( context, null /* parentNode */ ); // Act EventHandler <ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler( modelMetadata, null /* incomingValue */ ); handler(validationNode, e); // Assert Assert.False(context.ModelState.ContainsKey("foo")); }
public void SetProperty_PropertyIsSettable_SetterThrows_RecordsError() { // Arrange Person model = new Person() { DateOfBirth = new DateTime(1900, 1, 1) }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(model) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfDeath"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(1800, 1, 1), validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(null, bindingContext, propertyMetadata, dtoResult); // Assert Assert.AreEqual(@"Date of death can't be before date of birth. Parameter name: value", bindingContext.ModelState["foo"].Errors[0].Exception.Message); }
public void SetProperty_PropertyIsReadOnly_DoesNothing() { // Arrange ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single( o => o.PropertyName == "NonUpdateableProperty" ); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult( null /* model */ , validationNode ); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic( null, bindingContext, propertyMetadata, dtoResult, requiredValidator: null ); // Assert // If didn't throw, success! }
public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorPresent_AddsModelError() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(new Person()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "ValueTypeRequired"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.ValueTypeRequired"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.IsFalse(bindingContext.ModelState.IsValid, "ModelState should've been marked invalid."); Assert.AreEqual("Sample message", bindingContext.ModelState["foo.ValueTypeRequired"].Errors[0].ErrorMessage); }
public void NullCheckFailedHandler_ModelStateValid_CallbackReturnsNull_DoesNothing() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(context, null /* parentNode */); // Act ModelBinderErrorMessageProvider originalProvider = ModelBinderConfig.ValueRequiredErrorMessageProvider; try { ModelBinderConfig.ValueRequiredErrorMessageProvider = (ec, mm, value) => null; EventHandler <ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(modelMetadata, null /* incomingValue */); handler(validationNode, e); } finally { ModelBinderConfig.ValueRequiredErrorMessageProvider = originalProvider; } // Assert Assert.True(context.ModelState.IsValid); }
public Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { var validationNode = new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, _model); return(Task.FromResult(new ModelBindingResult(_model, bindingContext.ModelName, true, validationNode))); }
public void SetProperty_PropertyHasDefaultValue_SetsDefaultValue() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "PropertyWithDefaultValue"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); ModelValidator requiredValidator = context.GetValidators(propertyMetadata).Where(v => v.IsRequired).FirstOrDefault(); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(context, bindingContext, propertyMetadata, dtoResult, requiredValidator); // Assert var person = Assert.IsType <Person>(bindingContext.Model); Assert.Equal(123.456m, person.PropertyWithDefaultValue); Assert.True(context.ModelState.IsValid); }
public void BindSimpleCollection_SubBindingSucceeds() { // Arrange CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR"); Mock <IModelBinder> mockIntBinder = new Mock <IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider() }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object)); ModelValidationNode childValidationNode = null; mockIntBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns((HttpActionContext ec, ModelBindingContext mbc) => { Assert.Equal("someName", mbc.ModelName); childValidationNode = mbc.ValidationNode; mbc.Model = 42; return(true); }); // Act List <int> boundCollection = CollectionModelBinder <int> .BindSimpleCollection(context, bindingContext, new int[1], culture); // Assert Assert.Equal(new[] { 42 }, boundCollection.ToArray()); Assert.Equal(new[] { childValidationNode }, bindingContext.ValidationNode.ChildNodes.ToArray()); }
/// <summary> /// Creates a new <see cref="ModelBindingResult"/>. /// </summary> /// <param name="model">The model which was created by the <see cref="IModelBinder"/>.</param> /// <param name="key">The key using which was used to attempt binding the model.</param> /// <param name="isModelSet">A value that represents if the model has been set by the /// <see cref="IModelBinder"/>.</param> /// <param name="validationNode">A <see cref="ModelValidationNode"/> which captures the validation information. /// </param> public ModelBindingResult(object model, string key, bool isModelSet, ModelValidationNode validationNode) { Model = model; Key = key; IsModelSet = isModelSet; ValidationNode = validationNode; }
public void BindSimpleCollection_SubBindingSucceeds() { // Arrange ControllerContext controllerContext = new ControllerContext(); CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR"); ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)), ModelName = "someName", ModelBinderProviders = new ModelBinderProviderCollection(), ValueProvider = new SimpleValueProvider() }; ModelValidationNode childValidationNode = null; Mock <IExtensibleModelBinder> mockIntBinder = new Mock <IExtensibleModelBinder>(); mockIntBinder .Setup(o => o.BindModel(controllerContext, It.IsAny <ExtensibleModelBindingContext>())) .Returns( delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) { Assert.Equal("someName", mbc.ModelName); childValidationNode = mbc.ValidationNode; mbc.Model = 42; return(true); }); bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */); // Act List <int> boundCollection = CollectionModelBinder <int> .BindSimpleCollection(controllerContext, bindingContext, new int[1], culture); // Assert Assert.Equal(new[] { 42 }, boundCollection.ToArray()); Assert.Equal(new[] { childValidationNode }, bindingContext.ValidationNode.ChildNodes.ToArray()); }
public virtual bool TryValidateModel([NotNull] object model, string prefix) { if (BindingContext == null) { var message = Resources.FormatPropertyOfTypeCannotBeNull( nameof(BindingContext), typeof(Controller).FullName); throw new InvalidOperationException(message); } var modelMetadata = MetadataProvider.GetMetadataForType( modelAccessor: () => model, modelType: model.GetType()); var validationContext = new ModelValidationContext( MetadataProvider, BindingContext.ValidatorProvider, ModelState, modelMetadata, containerMetadata: null); var modelName = prefix ?? string.Empty; var validationNode = new ModelValidationNode(modelMetadata, modelName) { ValidateAllProperties = true }; validationNode.Validate(validationContext); return(ModelState.IsValid); }
public void CombineWith() { // Arrange List<string> log = new List<string>(); ModelValidationNode[] allChildNodes = new ModelValidationNode[] { new ModelValidationNode(GetModelMetadata(), "key1"), new ModelValidationNode(GetModelMetadata(), "key2"), new ModelValidationNode(GetModelMetadata(), "key3"), }; ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1"); parentNode1.ChildNodes.Add(allChildNodes[0]); parentNode1.Validating += delegate { log.Add("Validating parent1."); }; parentNode1.Validated += delegate { log.Add("Validated parent1."); }; ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2"); parentNode2.ChildNodes.Add(allChildNodes[1]); parentNode2.ChildNodes.Add(allChildNodes[2]); parentNode2.Validating += delegate { log.Add("Validating parent2."); }; parentNode2.Validated += delegate { log.Add("Validated parent2."); }; // Act parentNode1.CombineWith(parentNode2); parentNode1.Validate(new ControllerContext() { Controller = new EmptyController() }); // Assert CollectionAssert.AreEqual( new string[] { "Validating parent1.", "Validating parent2.", "Validated parent1.", "Validated parent2." }, log); CollectionAssert.AreEqual(allChildNodes, parentNode1.ChildNodes.ToArray()); }
public void DictionaryType_ValidationSuccessful() { // Arrange var modelStateDictionary = new ModelStateDictionary(); modelStateDictionary.Add("items[0].Key", new ModelState()); modelStateDictionary.Add("items[0].Value", new ModelState()); modelStateDictionary.Add("items[1].Key", new ModelState()); modelStateDictionary.Add("items[1].Value", new ModelState()); var model = new Dictionary <string, string>() { { "FooKey", "FooValue" }, { "BarKey", "BarValue" } }; var testValidationContext = GetModelValidationContext( model, typeof(Dictionary <string, string>), excludedTypes: null, modelStateDictionary: modelStateDictionary); var excludeTypeFilters = new List <IExcludeTypeValidationFilter>(); excludeTypeFilters.Add(new SimpleTypesExcludeFilter()); testValidationContext.ExcludeFilters = excludeTypeFilters; var validationContext = testValidationContext.ModelValidationContext; var validator = new DefaultObjectValidator( testValidationContext.ExcludeFilters, testValidationContext.ModelMetadataProvider); var topLevelValidationNode = new ModelValidationNode( "items", testValidationContext.ModelValidationContext.ModelExplorer.Metadata, testValidationContext.ModelValidationContext.ModelExplorer.Model) { ValidateAllProperties = true }; // Act validator.Validate(validationContext, topLevelValidationNode); // Assert Assert.True(validationContext.ModelState.IsValid); Assert.Equal(4, validationContext.ModelState.Count); var modelState = validationContext.ModelState["items[0].Key"]; Assert.Equal(ModelValidationState.Skipped, modelState.ValidationState); modelState = validationContext.ModelState["items[0].Value"]; Assert.Equal(ModelValidationState.Skipped, modelState.ValidationState); modelState = validationContext.ModelState["items[1].Key"]; Assert.Equal(ModelValidationState.Skipped, modelState.ValidationState); modelState = validationContext.ModelState["items[1].Value"]; Assert.Equal(ModelValidationState.Skipped, modelState.ValidationState); }
public ComplexModelDtoResult( object model, bool isModelBound, [NotNull] ModelValidationNode validationNode) { Model = model; IsModelBound = isModelBound; ValidationNode = validationNode; }
public void Validate_ThrowsIfControllerContextIsNull() { // Arrange ModelValidationNode node = new ModelValidationNode(GetModelMetadata(), "someKey"); // Act & assert Assert.ThrowsArgumentNull( delegate { node.Validate(null); }, "controllerContext"); }
public void PropertiesAreSet() { // Arrange ModelMetadata metadata = GetModelMetadata(); string modelStateKey = "someKey"; // Act ModelValidationNode node = new ModelValidationNode(metadata, modelStateKey); // Assert Assert.AreEqual(metadata, node.ModelMetadata); Assert.AreEqual(modelStateKey, node.ModelStateKey); Assert.IsNotNull(node.ChildNodes); Assert.AreEqual(0, node.ChildNodes.Count); }
public void ConstructorSetsCollectionInstance() { // Arrange ModelMetadata metadata = GetModelMetadata(); string modelStateKey = "someKey"; ModelValidationNode[] childNodes = new ModelValidationNode[] { new ModelValidationNode(metadata, "someKey0"), new ModelValidationNode(metadata, "someKey1") }; // Act ModelValidationNode node = new ModelValidationNode(metadata, modelStateKey, childNodes); // Assert CollectionAssert.AreEqual(childNodes, (ICollection)node.ChildNodes); }
public void Validate_Ordering() { // Proper order of invocation: // 1. OnValidating() // 2. Child validators // 3. This validator // 4. OnValidated() // Arrange List<string> log = new List<string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty")); node.Validating += delegate { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert CollectionAssert.AreEqual( new string[] { "In OnValidating()", "In IDataErrorInfo.get_Item('ValidStringProperty')", "In IDataErrorInfo.get_Error()", "In OnValidated()" }, log); }
public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorPresent_AddsModelError() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "ValueTypeRequired"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.ValueTypeRequired"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.False(bindingContext.ModelState.IsValid); Assert.Equal("Sample message", bindingContext.ModelState["foo.ValueTypeRequired"].Errors[0].ErrorMessage); }
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { var validationNode = new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, _model); return Task.FromResult(new ModelBindingResult(_model, bindingContext.ModelName, true, validationNode)); }
public void Validate_ValidateAllProperties_AddsValidationErrors() { // Arrange ValidateAllPropertiesModel model = new ValidateAllPropertiesModel() { RequiredString = null /* error */, RangedInt = 0 /* error */, ValidString = "dog" }; ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") { ValidateAllProperties = true }; controllerContext.Controller.ViewData.ModelState.AddModelError("theKey.RequiredString.Dummy", "existing Error Text"); // Act node.Validate(controllerContext); // Assert Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey.RequiredString"]); Assert.AreEqual("existing Error Text", controllerContext.Controller.ViewData.ModelState["theKey.RequiredString.Dummy"].Errors[0].ErrorMessage); Assert.AreEqual("The field RangedInt must be between 10 and 30.", controllerContext.Controller.ViewData.ModelState["theKey.RangedInt"].Errors[0].ErrorMessage); Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey.ValidString"]); Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey"]); }
public async Task BindSimpleCollection_SubBindingSucceeds() { // Arrange var culture = new CultureInfo("fr-FR"); var bindingContext = GetModelBindingContext(new SimpleHttpValueProvider()); ModelValidationNode childValidationNode = null; Mock.Get<IModelBinder>(bindingContext.OperationBindingContext.ModelBinder) .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) .Returns((ModelBindingContext mbc) => { Assert.Equal("someName", mbc.ModelName); childValidationNode = new ModelValidationNode("someName", mbc.ModelMetadata, mbc.Model); return Task.FromResult(new ModelBindingResult(42, mbc.ModelName, true, childValidationNode)); }); var modelBinder = new CollectionModelBinder<int>(); // Act var boundCollection = await modelBinder.BindSimpleCollection(bindingContext, new int[1], culture); // Assert Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray()); Assert.Equal(new[] { childValidationNode }, boundCollection.ValidationNode.ChildNodes.ToArray()); }
public void Validate_SkipsValidationIfSuppressed() { // Arrange List<string> log = new List<string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") { SuppressValidation = true }; node.Validating += (sender, e) => { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert CollectionAssert.AreEqual(new string[0], log, "Validate() should have been a no-op."); }
public void Validate_ThrowsIfControllerContextIsNull() { // Arrange ModelValidationNode node = new ModelValidationNode(GetModelMetadata(), "someKey"); // Act & assert ExceptionHelper.ExpectArgumentNullException( delegate { node.Validate(null); }, "controllerContext"); }
public void SetProperty_PropertyIsSettable_SetterThrows_RecordsError() { // Arrange Person model = new Person { DateOfBirth = new DateTime(1900, 1, 1) }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(model) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfDeath"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(1800, 1, 1), validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(null, bindingContext, propertyMetadata, dtoResult); // Assert Assert.Equal("Date of death can't be before date of birth." + Environment.NewLine + "Parameter name: value", bindingContext.ModelState["foo"].Errors[0].Exception.Message); }
public void Validator_IfValidateAllPropertiesSet_WithChildNodes_DoesNotAutoExpand() { // Arrange var testValidationContext = GetModelValidationContext( LonelyPerson, typeof(Person)); var validationContext = testValidationContext.ModelValidationContext; var validator = new DefaultObjectValidator( testValidationContext.ExcludeFilters, testValidationContext.ModelMetadataProvider); var modelExplorer = testValidationContext.ModelValidationContext.ModelExplorer; var topLevelValidationNode = new ModelValidationNode( "person", modelExplorer.Metadata, modelExplorer.Model) { ValidateAllProperties = true }; var propertyExplorer = modelExplorer.GetExplorerForProperty("Profession"); var childNode = new ModelValidationNode( "person.Profession", propertyExplorer.Metadata, propertyExplorer.Model); topLevelValidationNode.ChildNodes.Add(childNode); // Act validator.Validate(validationContext, topLevelValidationNode); // Assert var modelState = validationContext.ModelState; Assert.False(modelState.IsValid); // Since the model is invalid at property level there is no entry in the model state for top level node. Assert.Single(modelState.Keys, k => k == "person.Profession"); Assert.Equal(1, modelState.Count); }
public void NullCheckFailedHandler_ModelStateValid_CallbackReturnsNull_DoesNothing() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(controllerContext, null /* parentNode */); // Act ModelBinderErrorMessageProvider originalProvider = ModelBinderConfig.ValueRequiredErrorMessageProvider; try { ModelBinderConfig.ValueRequiredErrorMessageProvider = delegate { return null; }; EventHandler<ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(controllerContext, modelMetadata, null /* incomingValue */); handler(validationNode, e); } finally { ModelBinderConfig.ValueRequiredErrorMessageProvider = originalProvider; } // Assert Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid); }
public void SetProperty_PropertyIsReadOnly_DoesNothing() { // Arrange ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "NonUpdateableProperty"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(null, bindingContext, propertyMetadata, dtoResult); // Assert // If didn't throw, success! }
public void NullCheckFailedHandler_ModelStateAlreadyInvalid_DoesNothing() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; controllerContext.Controller.ViewData.ModelState.AddModelError("foo.bar", "Some existing error."); ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(controllerContext, null /* parentNode */); // Act EventHandler<ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(controllerContext, modelMetadata, null /* incomingValue */); handler(validationNode, e); // Assert Assert.False(controllerContext.Controller.ViewData.ModelState.ContainsKey("foo")); }
public void CombineWith_OtherNodeIsSuppressed_DoesNothing() { // Arrange List<string> log = new List<string>(); ModelValidationNode[] allChildNodes = new[] { new ModelValidationNode(GetModelMetadata(), "key1"), new ModelValidationNode(GetModelMetadata(), "key2"), new ModelValidationNode(GetModelMetadata(), "key3"), }; ModelValidationNode[] expectedChildNodes = new[] { allChildNodes[0] }; ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1"); parentNode1.ChildNodes.Add(allChildNodes[0]); parentNode1.Validating += delegate { log.Add("Validating parent1."); }; parentNode1.Validated += delegate { log.Add("Validated parent1."); }; ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2"); parentNode2.ChildNodes.Add(allChildNodes[1]); parentNode2.ChildNodes.Add(allChildNodes[2]); parentNode2.Validating += delegate { log.Add("Validating parent2."); }; parentNode2.Validated += delegate { log.Add("Validated parent2."); }; parentNode2.SuppressValidation = true; // Act parentNode1.CombineWith(parentNode2); parentNode1.Validate(new ControllerContext { Controller = new EmptyController() }); // Assert Assert.Equal(new[] { "Validating parent1.", "Validated parent1." }, log.ToArray()); Assert.Equal(expectedChildNodes, parentNode1.ChildNodes.ToArray()); }
public void SetProperty_SettingNullableTypeToNull_RequiredValidatorNotPresent_PropertySetterThrows_AddsRequiredMessageString() { // Arrange ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() { ModelMetadata = GetMetadataForObject(new ModelWhosePropertySetterThrows()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "NameNoAttribute"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.NameNoAttribute"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.IsFalse(bindingContext.ModelState.IsValid, "ModelState should've been marked invalid."); Assert.AreEqual(1, bindingContext.ModelState["foo.NameNoAttribute"].Errors.Count); Assert.AreEqual(@"This is a different exception. Parameter name: value", bindingContext.ModelState["foo.NameNoAttribute"].Errors[0].Exception.Message); }
private static IModelBinder CreateStringBinder() { var mockStringBinder = new Mock<IModelBinder>(); mockStringBinder .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) .Returns((ModelBindingContext mbc) => { if (mbc.ModelType == typeof(string)) { var model = "some-value"; var validationNode = new ModelValidationNode(mbc.ModelName, mbc.ModelMetadata, model); return Task.FromResult(new ModelBindingResult(model, mbc.ModelName, true, validationNode)); } return Task.FromResult<ModelBindingResult>(null); }); return mockStringBinder.Object; }
private static IModelBinder CreateIntBinder() { Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); mockIntBinder .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) .Returns(async (ModelBindingContext mbc) => { var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName); if (value != null) { var model = value.ConvertTo(mbc.ModelType); var modelValidationNode = new ModelValidationNode(mbc.ModelName, mbc.ModelMetadata, model); return new ModelBindingResult(model, mbc.ModelName, true, modelValidationNode); } return null; }); return mockIntBinder.Object; }
public void NullCheckFailedHandler_ModelStateValid_AddsErrorString() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(controllerContext, null /* parentNode */); // Act EventHandler<ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(controllerContext, modelMetadata, null /* incomingValue */); handler(validationNode, e); // Assert Assert.True(controllerContext.Controller.ViewData.ModelState.ContainsKey("foo")); Assert.Equal("A value is required.", controllerContext.Controller.ViewData.ModelState["foo"].Errors[0].ErrorMessage); }
public void Validate_PassesNullContainerInstanceIfCannotBeConvertedToProperType() { // Arrange List<string> log1 = new List<string>(); LoggingDataErrorInfoModel model1 = new LoggingDataErrorInfoModel(log1); ModelMetadata modelMetadata1 = GetModelMetadata(model1); List<string> log2 = new List<string>(); LoggingDataErrorInfoModel model2 = new LoggingDataErrorInfoModel(log2); ModelMetadata modelMetadata2 = GetModelMetadata(model2); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata1, "theKey"); node.ChildNodes.Add(new ModelValidationNode(modelMetadata2, "theKey.SomeProperty")); // Act node.Validate(controllerContext); // Assert CollectionAssert.AreEqual( new string[] { "In IDataErrorInfo.get_Error()" }, log1); CollectionAssert.AreEqual( new string[] { "In IDataErrorInfo.get_Error()" }, log2); }
public void SetProperty_PropertyHasDefaultValue_SetsDefaultValue() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "PropertyWithDefaultValue"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert var person = Assert.IsType<Person>(bindingContext.Model); Assert.Equal(123.456m, person.PropertyWithDefaultValue); Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid); }
public void Validate_SkipsRemainingValidationIfModelStateIsInvalid() { // Because a property validator fails, the model validator shouldn't run // Arrange List<string> log = new List<string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty")); node.Validating += delegate { log.Add("In OnValidating()"); }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert CollectionAssert.AreEqual( new string[] { "In OnValidating()", "In IDataErrorInfo.get_Item('InvalidStringProperty')", "In OnValidated()" }, log); Assert.AreEqual("Sample error message", controllerContext.Controller.ViewData.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage); }
public void SetProperty_PropertyIsSettable_CallsSetter() { // Arrange Person model = new Person(); ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(model) }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert validationNode.Validate(controllerContext); Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid); Assert.Equal(new DateTime(2001, 1, 1), model.DateOfBirth); }
public void Validate_SkipsValidationIfHandlerCancels() { // Arrange List<string> log = new List<string>(); LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log); ModelMetadata modelMetadata = GetModelMetadata(model); ControllerContext controllerContext = new ControllerContext() { Controller = new EmptyController() }; ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); node.Validating += (sender, e) => { log.Add("In OnValidating()"); e.Cancel = true; }; node.Validated += delegate { log.Add("In OnValidated()"); }; // Act node.Validate(controllerContext); // Assert CollectionAssert.AreEqual( new string[] { "In OnValidating()" }, log); }
public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()), }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid); validationNode.Validate(controllerContext, bindingContext.ValidationNode); Assert.False(controllerContext.Controller.ViewData.ModelState.IsValid); }
public void Validator_IfValidateAllPropertiesIsNotSet_DoesNotAutoExpand() { // Arrange var testValidationContext = GetModelValidationContext( LonelyPerson, typeof(Person)); var validationContext = testValidationContext.ModelValidationContext; var validator = new DefaultObjectValidator( testValidationContext.ExcludeFilters, testValidationContext.ModelMetadataProvider); var modelExplorer = testValidationContext.ModelValidationContext.ModelExplorer; // No ChildNode added var topLevelValidationNode = new ModelValidationNode( "person", modelExplorer.Metadata, modelExplorer.Model); // Act validator.Validate(validationContext, topLevelValidationNode); // Assert Assert.True(validationContext.ModelState.IsValid); // Since Person is not IValidatable and we do not look at its properties, the state is empty. Assert.Empty(validationContext.ModelState.Keys); }
public void SetProperty_SettingNullableTypeToNull_RequiredValidatorPresent_PropertySetterThrows_AddsRequiredMessageString() { // Arrange ControllerContext controllerContext = new ControllerContext { Controller = new EmptyController() }; ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext { ModelMetadata = GetMetadataForObject(new ModelWhosePropertySetterThrows()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "Name"); ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo.Name"); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); // Assert Assert.False(bindingContext.ModelState.IsValid); Assert.Equal(1, bindingContext.ModelState["foo.Name"].Errors.Count); Assert.Equal("This message comes from the [Required] attribute.", bindingContext.ModelState["foo.Name"].Errors[0].ErrorMessage); }
public async Task BindModel_UsesTheValidationNodeOnModelBindingResult_IfPresent() { // Arrange var valueProvider = new SimpleHttpValueProvider(); ModelValidationNode validationNode = null; var mockBinder = new Mock<IModelBinder>(); mockBinder .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) .Returns( delegate (ModelBindingContext context) { validationNode = new ModelValidationNode("someName", context.ModelMetadata, 42); return Task.FromResult( new ModelBindingResult(42, "someName", isModelSet: true, validationNode: validationNode)); }); var binder = CreateCompositeBinder(mockBinder.Object); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act var result = await binder.BindModelAsync(bindingContext); // Assert Assert.NotNull(result); Assert.True(result.IsModelSet); Assert.Same(validationNode, result.ValidationNode); }