public void Validate_ReturnsMemberName_IfItIsDifferentFromDisplayName() { // Arrange var metadata = _metadataProvider.GetMetadataForType(typeof(SampleModel)); var model = new SampleModel(); var attribute = new Mock<TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny<object>(), It.IsAny<ValidationContext>())) .Returns(new ValidationResult("Name error", new[] { "Name" })); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: null, model: model); // Act var results = validator.Validate(validationContext); // Assert ModelValidationResult validationResult = Assert.Single(results); Assert.Equal("Name", validationResult.MemberName); }
public void Validate_SetsMemberName_OnValidationContext_ForProperties( ModelMetadata metadata, object container, object model, string expectedMemberName) { // Arrange var attribute = new Mock<TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny<object>(), It.IsAny<ValidationContext>())) .Callback((object o, ValidationContext context) => { Assert.Equal(expectedMemberName, context.MemberName); }) .Returns(ValidationResult.Success) .Verifiable(); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: model); // Act var results = validator.Validate(validationContext); // Assert Assert.Empty(results); attribute.VerifyAll(); }
public void Validate_ReturnsSingleValidationResult_IfMemberNameSequenceIsEmpty() { // Arrange const string errorMessage = "Some error message"; var metadata = _metadataProvider.GetMetadataForType(typeof(string)); var container = "Hello"; var model = container.Length; var attribute = new Mock<TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny<object>(), It.IsAny<ValidationContext>())) .Returns(new ValidationResult(errorMessage, memberNames: null)); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: model); // Act var results = validator.Validate(validationContext); // Assert var validationResult = Assert.Single(results); Assert.Equal(errorMessage, validationResult.Message); Assert.Empty(validationResult.MemberName); }
public void Validate_ReturnsSingleValidationResult_IfOneMemberNameIsSpecified() { // Arrange const string errorMessage = "A different error message"; var metadata = _metadataProvider.GetMetadataForType(typeof(object)); var model = new object(); var attribute = new Mock<TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny<object>(), It.IsAny<ValidationContext>())) .Returns(new ValidationResult(errorMessage, new[] { "FirstName" })); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: null, model: model); // Act var results = validator.Validate(validationContext); // Assert ModelValidationResult validationResult = Assert.Single(results); Assert.Equal(errorMessage, validationResult.Message); Assert.Equal("FirstName", validationResult.MemberName); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { var dbcontext = (ShopDbContext)context.ActionContext.HttpContext .RequestServices.GetService(typeof(ShopDbContext)); return(null); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { string value = context.Model as string; if (!string.IsNullOrEmpty(value)) { if (!long.TryParse(value, out long number)) { yield return(new ModelValidationResult("", NotNumberError)); } else { if (number < 0) { yield return(new ModelValidationResult("", NotNumberError)); } if (value.Length < MinLength) { yield return(new ModelValidationResult("", string.Format(ApplicationResources.UserInterface.ModelsValidationMessages.PhoneNumberTooShort, MinLength))); } if (value.Length > 25) { yield return(new ModelValidationResult("", string.Format(ApplicationResources.UserInterface.ModelsValidationMessages.PhoneNumberTooLong, MaxLength))); } } } }
public void Validate_ReturnsExpectedResults_Collection() { // Arrange var validator = new DataSetValidator(); var model = DataSet <SampleModel> .Create(); model.AddRow(); var metadata = _metadataProvider.GetMetadataForProperty( typeof(SampleModelContainer), nameof(SampleModelContainer.SampleModel)); var validationContext = new ModelValidationContext( new ActionContext(), metadata, _metadataProvider, container: null, model: model); // Act var results = validator.Validate(validationContext); var resultsArray = results.ToArray(); // Assert Assert.NotNull(results); Assert.Single(resultsArray); Assert.Equal(ModelNames.CreatePropertyModelName("[0]", nameof(SampleModel.ID)), resultsArray[0].MemberName); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { IEnumerable <ModelValidationResult> result = Enumerable.Empty <ModelValidationResult>(); // Dependancy injection does not work with attributes so manually wire up the database context. using (NorthwindContext dbContext = DAL.Startup.NorthwindContext) { IRepository <Category, int> categories = new CategoryRepository(dbContext); int?value = context.Model as int?; // get the value of supplier (the type must match the column type) if (value == null) { // a supplier id must be supplied result = new List <ModelValidationResult>() { new ModelValidationResult("", "A category id must be provided") }; } else { Category category = categories.Fetch(value.Value); if (category == null) { result = new List <ModelValidationResult>() { new ModelValidationResult("", ErrorMessage) }; } } } return(result); }
public static IEnumerable<ModelValidationResult> Validate([NotNull] this ModelBindingContext bindingContext) { var validators = GetValidators(bindingContext, bindingContext.ModelMetadata); var compositeValidator = new CompositeModelValidator(validators); var modelValidationContext = new ModelValidationContext(bindingContext, bindingContext.ModelMetadata); return compositeValidator.Validate(modelValidationContext); }
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 IEnumerable <ModelValidationResult> Validate(ModelValidationContext mvContext) { var selector = _customizations.ToValidatorSelector(); var interceptor = _customizations.GetInterceptor() ?? _validator as IValidatorInterceptor; var context = new FluentValidation.ValidationContext(mvContext.Model, new FluentValidation.Internal.PropertyChain(), selector); if (interceptor != null) { // Allow the user to provide a customized context // However, if they return null then just use the original context. context = interceptor.BeforeMvcValidation((ControllerContext)mvContext.ActionContext, context) ?? context; } var result = _validator.Validate(context); if (interceptor != null) { // allow the user to provice a custom collection of failures, which could be empty. // However, if they return null then use the original collection of failures. result = interceptor.AfterMvcValidation((ControllerContext)mvContext.ActionContext, context, result) ?? result; } return(result.Errors.Select(x => new ModelValidationResult(x.PropertyName, x.ErrorMessage))); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { IEnumerable <ModelValidationResult> result = Enumerable.Empty <ModelValidationResult>(); // Dependancy injection does not work with attributes so manually wire up the database context. using (NorthwindContext dbContext = DAL.Startup.NorthwindContext) { IRepository <Order, int> repository = new OrderRepository(dbContext); int?value = context.Model as int?; if (value == null) { result = new List <ModelValidationResult>() { new ModelValidationResult("", "A order id must be provided") }; } else { Order model = repository.Fetch(value.Value); if (model == null) { result = new List <ModelValidationResult>() { new ModelValidationResult("", ErrorMessage) }; } } } return(result); }
public void Validate_IsValidFalse_StringLocalizerGetsArguments( ValidationAttribute attribute, string model, object[] values) { // Arrange var stringLocalizer = new Mock <IStringLocalizer>(); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute, stringLocalizer.Object); var metadata = _metadataProvider.GetMetadataForType(typeof(SampleModel)); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: null, model: model); // Act validator.Validate(validationContext); // Assert var json = Newtonsoft.Json.JsonConvert.SerializeObject(values) + " " + attribute.GetType().Name; stringLocalizer.Verify(l => l[LocalizationKey, values], json); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { var model = context.Model; if (model == null) { return(Enumerable.Empty <ModelValidationResult>()); } if (!(model is IValidatableObject validatable)) { throw new InvalidOperationException($"Incompatible Type:{model.GetType().FullName}"); } // The constructed ValidationContext is intentionally slightly different from what // DataAnnotationsModelValidator creates. The instance parameter would be context.Container // (if non-null) in that class. But, DataAnnotationsModelValidator _also_ passes context.Model // separately to any ValidationAttribute. var validationContext = new ValidationContext( instance: validatable, serviceProvider: context.ActionContext?.HttpContext?.RequestServices, items: null) { DisplayName = context.ModelMetadata.GetDisplayName(), MemberName = context.ModelMetadata.Name, }; return(ConvertResults(validatable.Validate(validationContext))); }
public void Validate_ReturnsExpectedResults( string errorMessage, IEnumerable <string> memberNames, IEnumerable <ModelValidationResult> expectedResults) { // Arrange var metadata = _metadataProvider.GetMetadataForProperty(typeof(string), nameof(string.Length)); var container = "Hello"; var model = container.Length; var attribute = new Mock <TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny <object>(), It.IsAny <ValidationContext>())) .Returns(new ValidationResult(errorMessage, memberNames)); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: model); // Act var results = validator.Validate(validationContext); // Assert Assert.Equal(expectedResults, results, ModelValidationResultComparer.Instance); }
public void Validate_IsValidFalse_StringLocalizerReturnsLocalizerErrorMessage() { // Arrange var metadata = _metadataProvider.GetMetadataForType(typeof(string)); var container = "Hello"; var attribute = new MaxLengthAttribute(4); attribute.ErrorMessage = "{0} should have no more than {1} characters."; var localizedString = new LocalizedString(attribute.ErrorMessage, "Longueur est invalide : 4"); var stringLocalizer = new Mock <IStringLocalizer>(); stringLocalizer.Setup(s => s[attribute.ErrorMessage, It.IsAny <object[]>()]).Returns(localizedString); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute, stringLocalizer.Object); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: "abcde"); // Act var result = validator.Validate(validationContext); // Assert var validationResult = result.Single(); Assert.Empty(validationResult.MemberName); Assert.Equal("Longueur est invalide : 4", validationResult.Message); }
public void Validate_Invalid() { // Arrange var metadata = _metadataProvider.GetMetadataForProperty(typeof(string), "Length"); var container = "Hello"; var model = container.Length; var attribute = new Mock <ValidationAttribute> { CallBase = true }; attribute.Setup(a => a.IsValid(model)).Returns(false); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: model); // Act var result = validator.Validate(validationContext); // Assert var validationResult = result.Single(); Assert.Empty(validationResult.MemberName); Assert.Equal(attribute.Object.FormatErrorMessage("Length"), validationResult.Message); }
public void Validate_ValidationResultSuccess() { // Arrange var metadata = _metadataProvider.GetMetadataForType(typeof(string)); var container = "Hello"; var model = container.Length; var attribute = new Mock <TestableValidationAttribute> { CallBase = true }; attribute .Setup(p => p.IsValidPublic(It.IsAny <object>(), It.IsAny <ValidationContext>())) .Returns(ValidationResult.Success); var validator = new DataAnnotationsModelValidator( new ValidationAttributeAdapterProvider(), attribute.Object, stringLocalizer: null); var validationContext = new ModelValidationContext( actionContext: new ActionContext(), modelMetadata: metadata, metadataProvider: _metadataProvider, container: container, model: model); // Act var result = validator.Validate(validationContext); // Assert Assert.Empty(result); }
/// <summary> /// Validate the constraint expression. /// </summary> /// <param name="bundle">Model to validate.</param> /// <param name="theContext">Validation context to capture the errors.</param> /// <returns> /// Return true if the constraint is valid, return false if /// the constraint is not valid. /// </returns> public override bool Validate(BundleModel bundle, ModelValidationContext theContext) { if (Expression.Node == null) { return(false); } var variableCaptureVisitor = new ConstraintVariableReferenceCaptureVisitor(); Expression.Node.AcceptVisitor(variableCaptureVisitor); var variableReferences = variableCaptureVisitor.GetReferences(); foreach (var singletonVariableReference in variableReferences.SingletonVariableReferences) { if (bundle.Variables.FirstOrDefault(_ => _.Name.IsEqualTo(singletonVariableReference.VariableName)) == null) { theContext.AddError($"Missing singleton variable {singletonVariableReference.VariableName}"); return(false); } } foreach (var aggregateVariableReference in variableReferences.AggregateVariableReferences) { if (bundle.Aggregates.FirstOrDefault(_ => _.Name.IsEqualTo(aggregateVariableReference.VariableName)) == null) { theContext.AddError($"Missing aggregate variable {aggregateVariableReference.VariableName}"); return(false); } } return(true); }
public async Task <ModelBindingResult> BindModelAsync( [NotNull] ParameterDescriptor parameter, [NotNull] ModelStateDictionary modelState, [NotNull] OperationBindingContext operationContext) { var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType); var modelBindingContext = GetModelBindingContext( parameter.Name, metadata, parameter.BindingInfo, modelState, operationContext); var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext); if (modelBindingResult != null && modelBindingResult.IsModelSet && modelBindingResult.ValidationNode != null) { var modelExplorer = new ModelExplorer( _modelMetadataProvider, metadata, modelBindingResult.Model); var validationContext = new ModelValidationContext( modelBindingContext.BindingSource, operationContext.ValidatorProvider, modelState, modelExplorer); _validator.Validate(validationContext, modelBindingResult.ValidationNode); } return(modelBindingResult); }
protected override async Task <bool> BindAsync( ModelBindingContext bindingContext, IFormatterBinderMetadata metadata) { var formatterContext = new InputFormatterContext(_actionContext, bindingContext.ModelType); var formatter = _formatterSelector.SelectFormatter(formatterContext); if (formatter == null) { var unsupportedContentType = Resources.FormatUnsupportedContentType( bindingContext.HttpContext.Request.ContentType); bindingContext.ModelState.AddModelError(bindingContext.ModelName, unsupportedContentType); // Should always return true so that the model binding process ends here. return(true); } bindingContext.Model = await formatter.ReadAsync(formatterContext); // Validate the deserialized object var validationContext = new ModelValidationContext( bindingContext.MetadataProvider, bindingContext.ValidatorProvider, bindingContext.ModelState, bindingContext.ModelMetadata, containerMetadata: null, excludeFromValidationDelegate: _mvcOptions.Options.ExcludeFromValidationDelegates); _bodyModelValidator.Validate(validationContext, bindingContext.ModelName); return(true); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { IEnumerable <ModelValidationResult> result = Enumerable.Empty <ModelValidationResult>(); // Dependancy injection does not work with attributes so manually wire up the database context. using (NorthwindContext dbContext = DAL.Startup.NorthwindContext) { IRepository <Territory, string> territories = new TerritoryRepository(dbContext); string value = context.Model as string; if (value == null) { result = new List <ModelValidationResult>() { new ModelValidationResult("", "A territory id must be provided") }; } else { Territory territory = territories.Fetch(value); if (territory == null) { result = new List <ModelValidationResult>() { new ModelValidationResult("", ErrorMessage) }; } } } return(result); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext context) { if (!(context.Model is string)) { return(Enumerable.Empty <ModelValidationResult>()); } var str = (string)context.Model; for (int i = 0; i < str.Length; i++) { if (str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z') { continue; } return(new List <ModelValidationResult> { new ModelValidationResult(context.ModelMetadata.PropertyName, $"{ErrorMessage}") }); } // рефакторинг инверсией // рефакторинг выделение идентичных действий //LINQ или Regex (скорее всего второй) return(Enumerable.Empty <ModelValidationResult>()); // возможно выброс исключения }
/// <summary> /// Builds a validator selector from the options specified in the attribute's properties. /// </summary> /// <param name="mvContext"></param> public IValidatorSelector ToValidatorSelector(ModelValidationContext mvContext) { IValidatorSelector selector; if (!string.IsNullOrEmpty(RuleSet)) { var rulesets = RuleSet.Split(',', ';') .Select(x => x.Trim()) .ToArray(); selector = CreateRulesetValidatorSelector(mvContext, rulesets); } else if (!string.IsNullOrEmpty(Properties)) { var properties = Properties.Split(',', ';') .Select(x => x.Trim()) .ToArray(); selector = CreateMemberNameValidatorSelector(mvContext, properties); } else { selector = CreateDefaultValidatorSelector(mvContext); } return(selector); }
public void Validate_ReturnsExpectedResults( ValidationResult[] innerResults, ModelValidationResult[] expectedResults) { // Arrange var adapter = new ValidatableObjectAdapter(); var model = new SampleModel(); foreach (var result in innerResults) { model.ValidationResults.Add(result); } var metadata = _metadataProvider.GetMetadataForProperty( typeof(SampleModelContainer), nameof(SampleModelContainer.SampleModel)); var validationContext = new ModelValidationContext( new ActionContext(), metadata, _metadataProvider, container: null, model: model); // Act var results = adapter.Validate(validationContext); // Assert Assert.NotNull(results); Assert.Equal(expectedResults, results, ModelValidationResultComparer.Instance); }
public void Validate_PassesExpectedNames( ModelMetadata metadata, string expectedDisplayName, string expectedMemberName) { // Arrange var adapter = new ValidatableObjectAdapter(); var model = new SampleModel(); var validationContext = new ModelValidationContext( new ActionContext(), metadata, _metadataProvider, container: new SampleModelContainer(), model: model); // Act var results = adapter.Validate(validationContext); // Assert Assert.NotNull(results); Assert.Empty(results); Assert.Equal(expectedDisplayName, model.DisplayName); Assert.Equal(expectedMemberName, model.MemberName); Assert.Equal(model, model.ObjectInstance); }
public void GetErrorMessage_DontLocalizeWhenErrorMessageResourceTypeGiven() { // Arrange var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var modelMetadata = metadataProvider.GetMetadataForProperty(typeof(string), "Length"); var stringLocalizer = new Mock <IStringLocalizer>(MockBehavior.Loose); var attribute = new TestValidationAttribute(); var adapter = new TestValidationAttributeAdapter(attribute, stringLocalizer.Object); var actionContext = new ActionContext(); var validationContext = new ModelValidationContext( actionContext, modelMetadata, metadataProvider, container: null, model: null); // Act adapter.GetErrorMessage(validationContext); // Assert Assert.True(attribute.Formatted); }
/// <summary> /// Updates the specified <paramref name="model"/> instance using the specified <paramref name="modelBinder"/> /// and the specified <paramref name="valueProvider"/> and executes validation using the specified /// <paramref name="validatorProvider"/>. /// </summary> /// <param name="model">The model instance to update and validate.</param> /// <param name="modelType">The type of model instance to update and validate.</param> /// <param name="prefix">The prefix to use when looking up values in the <paramref name="valueProvider"/>. /// </param> /// <param name="httpContext">The <see cref="HttpContext"/> for the current executing request.</param> /// <param name="modelState">The <see cref="ModelStateDictionary"/> used for maintaining state and /// results of model-binding validation.</param> /// <param name="metadataProvider">The provider used for reading metadata for the model type.</param> /// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param> /// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param> /// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the /// bound values.</param> /// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation /// on the model instance.</param> /// <param name="predicate">A predicate which can be used to /// filter properties(for inclusion/exclusion) at runtime.</param> /// <returns>A <see cref="Task"/> that on completion returns <c>true</c> if the update is successful</returns> public static async Task <bool> TryUpdateModelAsync( [NotNull] object model, [NotNull] Type modelType, [NotNull] string prefix, [NotNull] HttpContext httpContext, [NotNull] ModelStateDictionary modelState, [NotNull] IModelMetadataProvider metadataProvider, [NotNull] IModelBinder modelBinder, [NotNull] IValueProvider valueProvider, [NotNull] IObjectModelValidator objectModelValidator, [NotNull] IModelValidatorProvider validatorProvider, [NotNull] Func <ModelBindingContext, string, bool> predicate) { if (!modelType.IsAssignableFrom(model.GetType())) { var message = Resources.FormatModelType_WrongType( model.GetType().FullName, modelType.FullName); throw new ArgumentException(message, nameof(modelType)); } var modelMetadata = metadataProvider.GetMetadataForType(modelType); // Clear ModelStateDictionary entries for the model so that it will be re-validated. ClearValidationStateForModel(modelType, modelState, metadataProvider, prefix); var operationBindingContext = new OperationBindingContext { ModelBinder = modelBinder, ValidatorProvider = validatorProvider, MetadataProvider = metadataProvider, HttpContext = httpContext }; var modelBindingContext = new ModelBindingContext { Model = model, ModelMetadata = modelMetadata, ModelName = prefix, ModelState = modelState, ValueProvider = valueProvider, FallbackToEmptyPrefix = true, OperationBindingContext = operationBindingContext, PropertyFilter = predicate }; var modelBindingResult = await modelBinder.BindModelAsync(modelBindingContext); if (modelBindingResult != null) { var modelExplorer = new ModelExplorer(metadataProvider, modelMetadata, modelBindingResult.Model); var modelValidationContext = new ModelValidationContext(modelBindingContext, modelExplorer); modelValidationContext.RootPrefix = prefix; objectModelValidator.Validate(modelValidationContext); return(modelState.IsValid); } return(false); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext mvContext) { // Skip validation if model is null or the model has been marked for skipping. if (mvContext.Model == null || ShouldSkip(mvContext)) { return(Enumerable.Empty <ModelValidationResult>()); } var factory = mvContext.ActionContext.HttpContext.RequestServices.GetService(typeof(IValidatorFactory)) as IValidatorFactory; if (factory != null) { var validator = factory.GetValidator(mvContext.ModelMetadata.ModelType); if (validator != null) { var customizations = GetCustomizations(mvContext.ActionContext, mvContext.Model); if (customizations.Skip) { return(Enumerable.Empty <ModelValidationResult>()); } if (mvContext.Container != null) { var containerCustomizations = GetCustomizations(mvContext.ActionContext, mvContext.Container); if (containerCustomizations.Skip) { return(Enumerable.Empty <ModelValidationResult>()); } } var selector = customizations.ToValidatorSelector(); var interceptor = customizations.GetInterceptor() ?? (validator as IValidatorInterceptor); var context = new FluentValidation.ValidationContext(mvContext.Model, new FluentValidation.Internal.PropertyChain(), selector); context.RootContextData["InvokedByMvc"] = true; if (interceptor != null) { // Allow the user to provide a customized context // However, if they return null then just use the original context. context = interceptor.BeforeMvcValidation((ControllerContext)mvContext.ActionContext, context) ?? context; } var result = validator.Validate(context); if (interceptor != null) { // allow the user to provice a custom collection of failures, which could be empty. // However, if they return null then use the original collection of failures. result = interceptor.AfterMvcValidation((ControllerContext)mvContext.ActionContext, context, result) ?? result; } return(result.Errors.Select(x => new ModelValidationResult(x.PropertyName, x.ErrorMessage))); } } return(Enumerable.Empty <ModelValidationResult>()); }
public void ValidateWithAValidModelHasErrorsReturnsTrue() { var sut = MakeValidModel(); var validationContext = new ModelValidationContext(); new ModelValidator(sut).Validate(validationContext); Assert.That(validationContext.HasErrors, Is.False); }
public void ValidateWithAValidModelDoesNotPopulateErrors() { var sut = MakeValidModel(); var validationContext = new ModelValidationContext(); new ModelValidator(sut).Validate(validationContext); Assert.That(validationContext.Errors, Is.Empty); }
protected virtual void SetProperty( ModelBindingContext bindingContext, ModelExplorer modelExplorer, ModelMetadata propertyMetadata, ModelBindingResult dtoResult, IModelValidator requiredValidator) { var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase; var property = bindingContext.ModelType.GetProperty( propertyMetadata.PropertyName, bindingFlags); if (property == null || !property.CanWrite) { // nothing to do return; } object value; var hasDefaultValue = false; if (dtoResult.IsModelSet) { value = dtoResult.Model; } else { hasDefaultValue = TryGetPropertyDefaultValue(property, out value); } // 'Required' validators need to run first so that we can provide useful error messages if // the property setters throw, e.g. if we're setting entity keys to null. if (value == null) { var modelStateKey = dtoResult.Key; var validationState = bindingContext.ModelState.GetFieldValidationState(modelStateKey); if (validationState == ModelValidationState.Unvalidated) { if (requiredValidator != null) { var propertyExplorer = modelExplorer.GetExplorerForExpression(propertyMetadata, model: null); var validationContext = new ModelValidationContext(bindingContext, propertyExplorer); foreach (var validationResult in requiredValidator.Validate(validationContext)) { bindingContext.ModelState.TryAddModelError(modelStateKey, validationResult.Message); } } } } if (!dtoResult.IsModelSet && !hasDefaultValue) { // If we don't have a value, don't set it on the model and trounce a pre-initialized // value. return; } if (value != null || property.PropertyType.AllowsNullValue()) { try { property.SetValue(bindingContext.Model, value); } catch (Exception ex) { // don't display a duplicate error message if a binding error has already occurred for this field var targetInvocationException = ex as TargetInvocationException; if (targetInvocationException != null && targetInvocationException.InnerException != null) { ex = targetInvocationException.InnerException; } var modelStateKey = dtoResult.Key; var validationState = bindingContext.ModelState.GetFieldValidationState(modelStateKey); if (validationState == ModelValidationState.Unvalidated) { bindingContext.ModelState.AddModelError(modelStateKey, ex); } } } else { // trying to set a non-nullable value type to null, need to make sure there's a message var modelStateKey = dtoResult.Key; var validationState = bindingContext.ModelState.GetFieldValidationState(modelStateKey); if (validationState == ModelValidationState.Unvalidated) { var errorMessage = Resources.ModelBinderConfig_ValueRequired; bindingContext.ModelState.TryAddModelError(modelStateKey, errorMessage); } } }
private async Task PopulateArgumentsAsync( OperationBindingContext operationContext, ModelStateDictionary modelState, IDictionary<string, object> arguments, IEnumerable<ParameterDescriptor> parameterMetadata) { modelState.MaxAllowedErrors = _options.MaxModelValidationErrors; foreach (var parameter in parameterMetadata) { var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType); var parameterType = parameter.ParameterType; var modelBindingContext = GetModelBindingContext( parameter.Name, metadata, parameter.BindingInfo, modelState, operationContext); var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext); if (modelBindingResult != null && modelBindingResult.IsModelSet) { var modelExplorer = new ModelExplorer( _modelMetadataProvider, metadata, modelBindingResult.Model); arguments[parameter.Name] = modelBindingResult.Model; var validationContext = new ModelValidationContext( modelBindingResult.Key, modelBindingContext.BindingSource, operationContext.ValidatorProvider, modelState, modelExplorer); _validator.Validate(validationContext); } } }
// Returns true if validator execution adds a model error. private static bool RunValidator( IModelValidator validator, ModelBindingContext bindingContext, ModelExplorer propertyExplorer, string modelStateKey) { var validationContext = new ModelValidationContext(bindingContext, propertyExplorer); var addedError = false; foreach (var validationResult in validator.Validate(validationContext)) { bindingContext.ModelState.TryAddModelError(modelStateKey, validationResult.Message); addedError = true; } if (!addedError) { bindingContext.ModelState.MarkFieldValid(modelStateKey); } return addedError; }