Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
        public void SetProperty_SettingNullableTypeToNull_RequiredValidatorNotPresent_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 == "NameNoAttribute");
            ModelValidationNode   validationNode    = new ModelValidationNode(propertyMetadata, "foo.NameNoAttribute");
            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);
            ModelError modelError = Assert.Single(bindingContext.ModelState["foo.NameNoAttribute"].Errors);

            Assert.Equal(
                "This is a different exception." + Environment.NewLine + "Parameter name: value",
                modelError.Exception.Message);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        private void ValidateThis(HttpActionContext actionContext, ModelValidationNode parentNode)
        {
            ModelStateDictionary modelState = actionContext.ModelState;

            if (!modelState.IsValidField(ModelStateKey))
            {
                return; // short-circuit
            }

            // If 'this' is null and there is no parent, we cannot validate, and
            // the DataAnnotationsModelValidator will throw.   So we intercept here
            // to provide a catch-all value-required validation error
            if (parentNode == null && ModelMetadata.Model == null)
            {
                string trueModelStateKey = ModelBindingHelper.CreatePropertyModelName(ModelStateKey, ModelMetadata.GetDisplayName());
                modelState.AddModelError(trueModelStateKey, SRResources.Validation_ValueNotFound);
                return;
            }

            _validators = actionContext.GetValidators(ModelMetadata);

            object container = TryConvertContainerToMetadataType(parentNode);

            foreach (ModelValidator validator in _validators)
            {
                foreach (ModelValidationResult validationResult in validator.Validate(ModelMetadata, container))
                {
                    string trueModelStateKey = ModelBindingHelper.CreatePropertyModelName(ModelStateKey, validationResult.MemberName);
                    modelState.AddModelError(trueModelStateKey, validationResult.Message);
                }
            }
        }
Ejemplo n.º 6
0
        private void ValidateProperties(HttpActionContext actionContext)
        {
            // Based off CompositeModelValidator.
            ModelStateDictionary modelState = actionContext.ModelState;

            // DevDiv Bugs #227802 - Caching problem in ModelMetadata requires us to manually regenerate
            // the ModelMetadata.
            object        model           = ModelMetadata.Model;
            ModelMetadata updatedMetadata = actionContext.GetMetadataProvider().GetMetadataForType(() => model, ModelMetadata.ModelType);

            foreach (ModelMetadata propertyMetadata in updatedMetadata.Properties)
            {
                // Only want to add errors to ModelState if something doesn't already exist for the property node,
                // else we could end up with duplicate or irrelevant error messages.
                string propertyKeyRoot = ModelBindingHelper.CreatePropertyModelName(ModelStateKey, propertyMetadata.PropertyName);

                if (modelState.IsValidField(propertyKeyRoot))
                {
                    foreach (ModelValidator propertyValidator in actionContext.GetValidators(propertyMetadata))
                    {
                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(propertyMetadata, model))
                        {
                            string thisErrorKey = ModelBindingHelper.CreatePropertyModelName(propertyKeyRoot, propertyResult.MemberName);
                            modelState.AddModelError(thisErrorKey, propertyResult.Message);
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
        internal static void GetRequiredPropertiesCollection(
            HttpActionContext actionContext,
            ModelBindingContext bindingContext,
            out HashSet <string> requiredProperties,
            out Dictionary <string, ModelValidator> requiredValidators,
            out HashSet <string> skipProperties
            )
        {
            requiredProperties = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            requiredValidators = new Dictionary <string, ModelValidator>(
                StringComparer.OrdinalIgnoreCase
                );
            skipProperties = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            // Use attributes on the property before attributes on the type.
            ICustomTypeDescriptor modelDescriptor = TypeDescriptorHelper.Get(
                bindingContext.ModelType
                );
            PropertyDescriptorCollection propertyDescriptors = modelDescriptor.GetProperties();
            HttpBindingBehaviorAttribute typeAttr            = modelDescriptor
                                                               .GetAttributes()
                                                               .OfType <HttpBindingBehaviorAttribute>()
                                                               .SingleOrDefault();

            foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors)
            {
                string         propertyName      = propertyDescriptor.Name;
                ModelMetadata  propertyMetadata  = bindingContext.PropertyMetadata[propertyName];
                ModelValidator requiredValidator = actionContext
                                                   .GetValidators(propertyMetadata)
                                                   .Where(v => v.IsRequired)
                                                   .FirstOrDefault();
                requiredValidators[propertyName] = requiredValidator;

                HttpBindingBehaviorAttribute propAttr = propertyDescriptor.Attributes
                                                        .OfType <HttpBindingBehaviorAttribute>()
                                                        .SingleOrDefault();
                HttpBindingBehaviorAttribute workingAttr = propAttr ?? typeAttr;
                if (workingAttr != null)
                {
                    switch (workingAttr.Behavior)
                    {
                    case HttpBindingBehavior.Required:
                        requiredProperties.Add(propertyName);
                        break;

                    case HttpBindingBehavior.Never:
                        skipProperties.Add(propertyName);
                        break;
                    }
                }
                else if (requiredValidator != null)
                {
                    requiredProperties.Add(propertyName);
                }
            }
        }
        public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorPresent_AddsModelError()
        {
            // Arrange
            HttpActionContext   context        = ContextUtil.CreateActionContext();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                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
                );
            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(
                "Sample message",
                bindingContext.ModelState["foo.ValueTypeRequired"].Errors[0].ErrorMessage
                );
        }
        public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback()
        {
            // Arrange
            HttpActionContext   context        = ContextUtil.CreateActionContext();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                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
                );
            ModelValidator requiredValidator = context
                                               .GetValidators(propertyMetadata)
                                               .Where(v => v.IsRequired)
                                               .FirstOrDefault();

            TestableMutableObjectModelBinder testableBinder =
                new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(
                context,
                bindingContext,
                propertyMetadata,
                dtoResult,
                requiredValidator
                );

            // Assert
            Assert.True(context.ModelState.IsValid);
            validationNode.Validate(context, bindingContext.ValidationNode);
            Assert.False(context.ModelState.IsValid);
        }