Validate DateTime with FluentValidator

[亡魂溺海] 提交于 2019-11-29 11:44:55

问题


This is my ViewModel class:

public class CreatePersonModel
{
    public string Name { get; set; }
    public DateTime DateBirth { get; set; }
    public string Email { get; set; }
}

CreatePerson.cshtml

@model ViewModels.CreatePersonModel
@{
    ViewBag.Title = "Create Person";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm())
{
    <fieldset>
        <legend>RegisterModel</legend>

        @Html.EditorForModel()

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

CreatePersonValidator.cs

public class CreatePersonValidator : AbstractValidator<CreatePersonModel>
{
    public CreatePersonValidator()
    {
        RuleFor(p => p.Name)
            .NotEmpty().WithMessage("campo obrigatório")
            .Length(5, 30).WithMessage("mínimo de {0} e máximo de {1} caractéres", 5, 30)
            .Must((p, n) => n.Any(c => c == ' ')).WithMessage("deve conter nome e sobrenome");

        RuleFor(p => p.DateBirth)
            .NotEmpty().WithMessage("campo obrigatório")
            .LessThan(p => DateTime.Now).WithMessage("a data deve estar no passado");

        RuleFor(p => p.Email)
            .NotEmpty().WithMessage("campo obrigatório")
            .EmailAddress().WithMessage("email inválido")
            .OnAnyFailure(p => p.Email = "");
    }
}

When trying to create a person with an invalid date format:

Observations

As in my CreatePersonModel class the DateBirth property is a DateTime type, the asp.net MVC validation has done for me.

But I want to customize the error message using the FluentValidation.

I do not want to change the type of property for various reasons such as:

In a CreatePersonValidator.cs class, validation is to check if the date is in the past:

.LessThan (p => DateTime.Now)

Question

How to customize the error message without using DataAnnotations (using FluentValidator).


回答1:


public CreatePersonValidator()
{
    RuleFor(courseOffering => courseOffering.StartDate)
       .Must(BeAValidDate).WithMessage("Start date is required");

    //....
}

private bool BeAValidDate(DateTime date)
{
    return !date.Equals(default(DateTime));
}



回答2:


Have a look at the Fluent Validation documentation on GitHub:

https://github.com/JeremySkinner/FluentValidation/wiki

Try adding a RegEx Validator to ensure that the user's input (a string) can be parsed as a date correctly, prior to applying the Less Than Validator.

EDIT

Having run few test cases and looked at the source code for Fluent Validator I concede that the above approach won't work.

The standard error you get is added during the Model Binding phase, which happens before the fluent validation framework can access and check the model.

I assumed that the framework's authors had been clever and were injecting their validation code into the model binding phase. Looks like they aren't.

So the short answer is what you want to do does not appear to be possible.




回答3:


As Stewart mentioned, it's not possible to use FluentValidation alone to get in front of the model binding in this way. I'd offer up two ideas/suggestions though:

  1. If you really can't change the ViewModel type from DateTime to string, you could always clear the model state yourself after model binding and then run the validator manually (I'm assuming you've wired FluentValidation to execute automatically after model binding).
  2. In scenarios like this, I would change the property to a string, but then use AutoMapper to map that into a DateTime for whatever business object / domain model / service contract request I need it to ultimately become. That way, you get the most flexibility with parsing and conversion on both sides of the model binding.



回答4:


Try this one

RuleFor(f =>
        f.StartDate).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty()
                    .Must(date => date != default(DateTime))
                    .WithMessage("Start date is required");


来源:https://stackoverflow.com/questions/7777985/validate-datetime-with-fluentvalidator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!