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 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); ModelError error = Assert.Single(bindingContext.ModelState["foo.Name"].Errors); Assert.Equal("This message comes from the [Required] attribute.", error.ErrorMessage); }
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.False(bindingContext.ModelState.IsValid); Assert.Equal(1, bindingContext.ModelState["foo.NameNoAttribute"].Errors.Count); Assert.Equal(@"This is a different exception. Parameter name: value", bindingContext.ModelState["foo.NameNoAttribute"].Errors[0].Exception.Message); }
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 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 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 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 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); }
protected override void SetProperty( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ModelMetadata propertyMetadata, ComplexModelDtoResult dtoResult ) { SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); }
public virtual void SetPropertyPublic( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ModelMetadata propertyMetadata, ComplexModelDtoResult dtoResult ) { base.SetProperty(controllerContext, bindingContext, propertyMetadata, dtoResult); }
public void Constructor_SetsProperties() { // Arrange ModelValidationNode validationNode = GetValidationNode(); // Act ComplexModelDtoResult result = new ComplexModelDtoResult("some string", validationNode); // Assert Assert.AreEqual("some string", result.Model); Assert.AreEqual(validationNode, result.ValidationNode); }
public void Constructor_SetsProperties() { // Arrange ModelValidationNode validationNode = GetValidationNode(); // Act ComplexModelDtoResult result = new ComplexModelDtoResult("some string", validationNode); // Assert Assert.Equal("some string", result.Model); Assert.Equal(validationNode, result.ValidationNode); }
public void Constructor_SetsProperties() { // Arrange var validationNode = GetValidationNode(); // Act var result = new ComplexModelDtoResult( "some string", isModelBound: true, validationNode: validationNode); // Assert Assert.Equal("some string", result.Model); Assert.True(result.IsModelBound); Assert.Equal(validationNode, result.ValidationNode); }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (!CanBindType(bindingContext.ModelType)) { return(false); } if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(false); } bindingContext.Model = Activator.CreateInstance(bindingContext.ModelType); ComplexModelDto dto = new ComplexModelDto(bindingContext.ModelMetadata, bindingContext.PropertyMetadata.Values); ModelBindingContext subContext = new ModelBindingContext(bindingContext) { ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)), ModelName = bindingContext.ModelName, }; actionContext.Bind(subContext); foreach (KeyValuePair <ModelMetadata, ComplexModelDtoResult> item in dto.Results) { ModelMetadata propertyMetadata = item.Key; ComplexModelDtoResult dtoResult = item.Value; if (dtoResult != null) { PropertyInfo propertyInfo = bindingContext.ModelType.GetProperty(propertyMetadata.PropertyName); if (propertyInfo.CanWrite) { propertyInfo.SetValue(bindingContext.Model, dtoResult.Model); } } } return(true); }
public void BindModel() { // Arrange ControllerContext controllerContext = new ControllerContext(); MyModel model = new MyModel(); ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => model, typeof(MyModel)); ComplexModelDto dto = new ComplexModelDto(modelMetadata, modelMetadata.Properties); Mock <IExtensibleModelBinder> mockStringBinder = new Mock <IExtensibleModelBinder>(); mockStringBinder .Setup(b => b.BindModel(controllerContext, It.IsAny <ExtensibleModelBindingContext>())) .Returns( delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) { Assert.AreEqual(typeof(string), mbc.ModelType); Assert.AreEqual("theModel.StringProperty", mbc.ModelName); mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.StringProperty"); mbc.Model = "someStringValue"; return(true); }); Mock <IExtensibleModelBinder> mockIntBinder = new Mock <IExtensibleModelBinder>(); mockIntBinder .Setup(b => b.BindModel(controllerContext, It.IsAny <ExtensibleModelBindingContext>())) .Returns( delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) { Assert.AreEqual(typeof(int), mbc.ModelType); Assert.AreEqual("theModel.IntProperty", mbc.ModelName); mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.IntProperty"); mbc.Model = 42; return(true); }); Mock <IExtensibleModelBinder> mockDateTimeBinder = new Mock <IExtensibleModelBinder>(); mockDateTimeBinder .Setup(b => b.BindModel(controllerContext, It.IsAny <ExtensibleModelBindingContext>())) .Returns( delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) { Assert.AreEqual(typeof(DateTime), mbc.ModelType); Assert.AreEqual("theModel.DateTimeProperty", mbc.ModelName); return(false); }); ModelBinderProviderCollection binders = new ModelBinderProviderCollection(); binders.RegisterBinderForType(typeof(string), mockStringBinder.Object, true /* suppressPrefixCheck */); binders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */); binders.RegisterBinderForType(typeof(DateTime), mockDateTimeBinder.Object, true /* suppressPrefixCheck */); ExtensibleModelBindingContext parentBindingContext = new ExtensibleModelBindingContext() { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)), ModelName = "theModel", ModelBinderProviders = binders }; ComplexModelDtoModelBinder binder = new ComplexModelDtoModelBinder(); // Act bool retVal = binder.BindModel(controllerContext, parentBindingContext); // Assert Assert.IsTrue(retVal); Assert.AreEqual(dto, parentBindingContext.Model, "The return model should have been the original DTO."); ComplexModelDtoResult stringDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(string)).First()]; Assert.AreEqual("someStringValue", stringDtoResult.Model); Assert.AreEqual("theModel.StringProperty", stringDtoResult.ValidationNode.ModelStateKey); ComplexModelDtoResult intDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(int)).First()]; Assert.AreEqual(42, intDtoResult.Model); Assert.AreEqual("theModel.IntProperty", intDtoResult.ValidationNode.ModelStateKey); ComplexModelDtoResult dateTimeDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(DateTime)).First()]; Assert.IsNull(dateTimeDtoResult); }
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); }
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 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); }
protected override void SetProperty(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ModelMetadata propertyMetadata, ComplexModelDtoResult dtoResult) { SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult); }
public virtual void SetPropertyPublic(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ModelMetadata propertyMetadata, ComplexModelDtoResult dtoResult) { base.SetProperty(controllerContext, bindingContext, propertyMetadata, dtoResult); }
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 bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (!CanBindType(bindingContext.ModelType)) { return(false); } if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(false); } //创建针对目标类型的空对象 var ins = DynamicModelBuilder.GetInstance <IContact>(parent: bindingContext.ModelType, propAttrProvider: () => { return(new List <PropertyCustomAttributeUnit> { new PropertyCustomAttributeUnit { prop_name = "phone", attrs = new List <PropertyCustomAttribute> { new PropertyCustomAttribute { attr_type = "System.ComponentModel.DataAnnotations.RequiredAttribute,System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", ctor_arg_types = "", ctor_arg_values = new object[0], error_msg = "姓名不能为空", error_msg_res_name = "", error_msg_res_type = "" } } } }); }); //bindingContext.Model = Activator.CreateInstance(bindingContext.ModelType); bindingContext.Model = ins; //创建针对目标类型的ComplexModelDto //创建ModelBindingContext,并将ComplexModelDto作为Model,驱动新一轮的Model绑定 ComplexModelDto dto = new ComplexModelDto(bindingContext.ModelMetadata, bindingContext.PropertyMetadata.Values); ModelBindingContext subContext = new ModelBindingContext(bindingContext) { ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)), ModelName = bindingContext.ModelName }; actionContext.Bind(subContext); //从ComplexModelDto获取相应的值并为相应的属性赋值 foreach (KeyValuePair <ModelMetadata, ComplexModelDtoResult> item in dto.Results) { ModelMetadata propertyMetadata = item.Key; ComplexModelDtoResult dtoResult = item.Value; if (dtoResult != null) { PropertyInfo propertyInfo = bindingContext.ModelType.GetProperty(propertyMetadata.PropertyName); if (propertyInfo.CanWrite) { propertyInfo.SetValue(bindingContext.Model, dtoResult.Model); } } } return(true); }