与ASP不一致的流畅验证。净MVC 5

时间:2022-12-04 20:19:42

I'm using Fluent Validation v5.5 with ASP.NET v5.2.2 and I'm getting some inconsistent results with the validation.

我正在使用Fluent Validation v5.5和ASP。我得到的结果与验证不一致。

My view model is:

我的视图模型是:

public class QuoteViewModel
{
    [Display(Name = @"Day")]
    public int DateOfBirthDay { get; set; }

    [Display(Name = @"Month")]
    public int DateOfBirthMonth { get; set; }

    [Display(Name = @"Year")]
    public int DateOfBirthYear { get; set; }

    [Display(Name = @"Gender")]
    public Gender? Gender { get; set; }

    [Display(Name = @"State")]
    public int StateId { get; set; }
}

My controller method is:

我的控制器方法是:

public ActionResult Quote(QuoteViewModel viewModel)
{
    var _validator = new QuoteValidator();
    var results = _validator.Validate(viewModel);

    if (!ModelState.IsValid)
    {
        return Json(false);
    }

    return Json(true);
}

My validator is:

我的验证器是:

public class QuoteValidator : AbstractValidator<QuoteViewModel>
{
    public QuoteValidator()
    {
        RuleFor(x => x.Gender).NotEmpty();
        RuleFor(x => x.StateId).NotEmpty();
        RuleFor(x => x.DateOfBirthDay).NotEmpty().InclusiveBetween(1, 31);
        RuleFor(x => x.DateOfBirthMonth).NotEmpty().InclusiveBetween(1, 12);
        RuleFor(x => x.DateOfBirthYear).NotEmpty().LessThanOrEqualTo(DateTime.UtcNow.Year);
    }
}

I'm running a test that posts all blank value form fields. Thus the view model fields retain default values after the view model object is created.

我正在运行一个测试,该测试将发布所有空白值表单字段。因此,在创建视图模型对象之后,视图模型字段保留默认值。

For comparison, in the controller I'm running the validation explicitly and the results aren't consistent with the validation result in ModelState.

相比之下,在控制器中,我显式地运行验证,结果与模型状态的验证结果不一致。

ModelState is showing 4 errors, all triggered by NotEmpty rules. NotEmpty on the nullable enum Gender doesn't seem to trigger.

ModelState显示了4个错误,都是由NotEmpty规则触发的。在可空的enum性别上的NotEmpty似乎并没有触发。

The explicit validation is returning 7 out of 8 errors, the LessThanOrEqualTo rule won't fire since the DateOfBirthYear defaults to zero.

显式验证是返回8个错误中的7个,LessThanOrEqualTo规则不会触发,因为诞生年的日期默认为零。

My pain point is I can't figure out why ModelState is missing the NotEmpty error on the nullable enum Gender.

我的痛处是,我无法弄清楚为什么ModelState丢失了可空enum性别上的NotEmpty错误。

The only way I've been able to trigger that error is to post just the Gender value.

我能够触发这个错误的唯一方法是只发布性别值。

Please help.

请帮助。

EDIT:

编辑:

After stepping through some code, it appears that the issue is related to the Fluent Validation RequiredFluentValidationPropertyValidator. The Gender field is a nullable value type which is bound to null. The following snippet from RequiredFluentValidationPropertyValidator prevents validation:

在执行了一些代码之后,这个问题似乎与Fluent验证请求fluentvalidationpropertyvalidator有关。性别字段是一个可空值类型,它被绑定为null。以下来自RequiredFluentValidationPropertyValidator的代码片段阻止了验证:

ShouldValidate = isNonNullableValueType && nullWasSpecified;

1 个解决方案

#1


2  

!ModelState.IsValid doesn't use your validation result it uses defaulf MVC validation (that can be added through DataAnnotations). You have to check !results.IsValid instead which contains the validation result of your QuoteValidator.

模型状态。IsValid没有使用您的验证结果,它使用了defaulf MVC验证(可以通过dataannotation添加)。你得检查一下,结果。相反,它包含QuoteValidator的验证结果。

If you want to use default ModelState.IsValid you have to mark your model with validator attribute:

如果您想使用默认的模型状态。您必须使用validator属性标记您的模型:

[Validator(typeof(QuoteValidator))]
public class QuoteViewModel
{
    [Display(Name = @"Day")]
    public int DateOfBirthDay { get; set; }

    [Display(Name = @"Month")]
    public int DateOfBirthMonth { get; set; }

    [Display(Name = @"Year")]
    public int DateOfBirthYear { get; set; }

    [Display(Name = @"Gender")]
    public Gender? Gender { get; set; }

    [Display(Name = @"State")]
    public int StateId { get; set; }
}

And add the following line to your Application_Start method:

并在您的Application_Start方法中添加以下行:

protected void Application_Start() {
    FluentValidationModelValidatorProvider.Configure();
}

#1


2  

!ModelState.IsValid doesn't use your validation result it uses defaulf MVC validation (that can be added through DataAnnotations). You have to check !results.IsValid instead which contains the validation result of your QuoteValidator.

模型状态。IsValid没有使用您的验证结果,它使用了defaulf MVC验证(可以通过dataannotation添加)。你得检查一下,结果。相反,它包含QuoteValidator的验证结果。

If you want to use default ModelState.IsValid you have to mark your model with validator attribute:

如果您想使用默认的模型状态。您必须使用validator属性标记您的模型:

[Validator(typeof(QuoteValidator))]
public class QuoteViewModel
{
    [Display(Name = @"Day")]
    public int DateOfBirthDay { get; set; }

    [Display(Name = @"Month")]
    public int DateOfBirthMonth { get; set; }

    [Display(Name = @"Year")]
    public int DateOfBirthYear { get; set; }

    [Display(Name = @"Gender")]
    public Gender? Gender { get; set; }

    [Display(Name = @"State")]
    public int StateId { get; set; }
}

And add the following line to your Application_Start method:

并在您的Application_Start方法中添加以下行:

protected void Application_Start() {
    FluentValidationModelValidatorProvider.Configure();
}