26

这是我的ViewModel类:

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

创建人.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 = "");
    }
}

尝试使用无效日期格式创建人员时:

尝试救人时出错

观察

在我的 CreatePersonModel 类中,该DateBirth属性是一种DateTime类型,asp.net MVC 验证已为我完成。

但我想使用 FluentValidation自定义错误消息。

由于各种原因,我不想更改属性的类型,例如:

在一个CreatePersonValidator.cs 类中,验证是检查日期是否过去:

.LessThan (p => DateTime.Now)

问题

如何在不使用 DataAnnotations(使用 FluentValidator)的情况下自定义错误消息。

4

5 回答 5

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

    //....
}

private bool BeAValidDate(DateTime date)
{
    return !date.Equals(default(DateTime));
}
于 2012-08-31T10:08:06.277 回答
4

查看 GitHub 上的 Fluent Validation 文档:

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

在应用小于验证器之前,尝试添加正则表达式验证器以确保用户的输入(字符串)可以正确解析为日期。

编辑

运行了几个测试用例并查看了 Fluent Validator 的源代码后,我承认上述方法行不通。

您获得的标准错误是在模型绑定阶段添加的,该阶段发生在流式验证框架可以访问和检查模型之前。

我假设框架的作者很聪明,并且将他们的验证代码注入到模型绑定阶段。看起来他们不是。

所以简短的回答是你想做的事情似乎是不可能的。

于 2011-10-18T13:27:15.257 回答
1

正如 Stewart 所提到的,以这种方式单独使用 FluentValidation 来获取模型绑定是不可能的。不过,我会提出两个想法/建议:

  1. 如果您确实无法将 ViewModel 类型从 DateTime 更改为字符串,则始终可以在模型绑定后自己清除模型状态,然后手动运行验证器(我假设您已将 FluentValidation 连接到模型绑定后自动执行)。
  2. 在这样的场景中,我会将属性更改为字符串,然后使用AutoMapper将其映射到 DateTime 以用于我最终需要它成为的任何业务对象/域模型/服务合同请求。 这样,您就可以在模型绑定的两侧获得最大的解析和转换灵活性。
于 2012-02-08T03:07:03.503 回答
1

试试这个

RuleFor(f =>
        f.StartDate).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty()
                    .Must(date => date != default(DateTime))
                    .WithMessage("Start date is required");
于 2015-07-16T05:53:59.503 回答
0

DateTime?使用非常简单的代码来解决这个问题。如果您使用内置验证器NotNull(),那么您将获得客户端验证,这有两个好处。

  1. 您不必担心人们在其他答案中谈论的所有模型绑定内容。是客户端!;)
  2. 用户输入的日期不会被“清除”。无效日期将被 Post 设置为 null,模型绑定为 null,验证错误,现在用日期中的 null 值响应视图。这发生得很快,因此用户看不到日期有什么问题。

这是我使用的代码:

RuleFor(x => x.CompleteDate).NotNull().WithMessage("Complete Date is not a valid date.");

我在2021年 11 月 31 日(11 月没有第 31 天)对它进行了测试,它在客户端验证方面效果很好。

赢!

于 2021-10-21T12:13:48.920 回答