2
votes

I'm trying out Fluent Validation using the Contoso University project.

So I've added a validator attribute to an existing class:

[Validator(typeof(PersonValidator))]
public abstract class Person
{
    public int ID { get; set; }

    [Required]
    [StringLength(50)]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

My PersonValidator doesn't do anything yet:

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
    }
}

But when I access the create page for a Student my debugger stops on the EditorFor line....

 @Html.EditorFor(model => model.LastName, 
      new { htmlAttributes = new { @class = "form-control" } })

….and I get an error:

Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: required

I don't appear to have the same validation on the same element more than once, so why am I getting the error? Can Fluent Validation work alongside MVC's built in validation?

3
Looks very similar to this SO threaddummyDev

3 Answers

2
votes

This can happen if you use FluentValidation with DataAnnotations. Try to do something like this in Application_Start

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
FluentValidationModelValidatorProvider.Configure(provider => provider.AddImplicitRequiredValidator = false);
var fluentValidationModelValidatorProvider = new FluentValidationModelValidatorProvider(new AttributedValidatorFactory());
ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
0
votes

As per this page, you can try removing the DataAnnotations validations.

Compatibility with ASP.NET’s built-in Validation By default, after FluentValidation is executed then any other validator providers will also have a chance to execute as well. This means you can mix FluentValidation with DataAnnotations attributes (or any other ASP.NET ModelValidatorProvider implementation).

If you want to disable this behaviour so that FluentValidation is the only validation library that executes, you can set the RunDefaultMvcValidationAfterFluentValidationExecutes to false in your application startup routine:

services.AddMvc().AddFluentValidation(fv => {
 fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
});

Note If you do set RunDefaultMvcValidationAfterFluentValidationExecutes to false then support for IValidatableObject will also be disabled.

Hope this helps!

0
votes

I'm not sure why it would add an implicit required validator to a string field, but the problem went away when I configured the Fluent Validation Provider to not add implicit required validators in my Global.asax.cs file:

FluentValidationModelValidatorProvider.Configure(provider 
    => provider.AddImplicitRequiredValidator = false);

I didn't want to change the behaviour of any existing data annotations so that is all I added