如何使用FluentValidation强制显示验证摘要?

5

我已经在我的ASP.Net MVC 3项目中设置了FluentValidation。我有一个表单,其中有两个输入框。任何一个可以为空,但不能同时为空。

这是我的代码:

RuleFor(x => x.username)
    .NotEmpty()
    .When(x => string.IsNullOrEmpty(x.email) == true)
    .WithMessage("Please enter either a username or email address")

这样可以正确地将错误信息直接放在我的用户名字段上方。然而,当两个字段都为空时,我更希望验证摘要显示该消息。

有没有办法实现这一点?我一直在想,如果其他两个字段为空,我可以在模型中创建一个未使用的字段,并在其中放置该错误信息。

RuleFor(x => x.unused_field)
    .NotEmpty()
    .When(x => string.IsNullOrEmpty(x.email) == true && string.IsNullOrEmpty(x.username) == true)
    .WithMessage("Please enter either a username or email address")

但这种方法感觉很笨拙。有没有一种方法可以直接向验证摘要中添加消息?


从未尝试,只是一个想法:RuleFor(x => x).Must(x => !string.IsNullOrEmpty(x.email) && !string.IsNullOrEmpty(x.username))... - Ramunas
2个回答

6
我找到的唯一参考资料是这个
如果你的模型很简单,而且这条规则是唯一的规则,那么这条规则就足够了。
RuleFor(x => x)
        .Must(x => !string.IsNullOrWhiteSpace(x.Email) || !string.IsNullOrWhiteSpace(x.UserName))
        .WithName(".") // This adds error message to MVC validation summary
        .WithMessage("Please enter either a username or email address");

只需在视图中添加@Html.ValidationSummary(),您就可以开始使用了。

但是,如果您要对模型添加更多规则,则据我所知只有一种“hacky”方法:
在控制器操作中添加以下内容:

if (!ModelState.IsValid)
{
    if (ModelState["."].Errors.Any())
    {
        ModelState.AddModelError(string.Empty, ModelState["."].Errors.First().ErrorMessage);
    }
    // ...
}

这将会把"."属性中的第一个错误信息添加到模型属性中(请根据您的需求进行调整)。此外,您需要使用@Html.ValidationSummary(true)来仅在验证摘要中显示模型级别的错误。

第三个选项:向unused_property添加规则,并使用@Html.ValidationSummaryFor(x => x.unused_property)作为验证摘要。


第一个选项为什么只需要一条规则就可以工作呢?之后我添加更多规则不会影响它吗? - roryok
因为在第一个选项中,您有@Html.ValidationSummary(),它显示了您拥有的所有错误,包括特定于属性的错误。 - Ramunas
我不介意在有其他验证错误时出现验证摘要。我只是不希望在两者都为空时显示单个错误。 - roryok
那么?我提供的两个解决方案都不适用于你吗?第二个有什么问题吗? - Ramunas
我不是在抱怨 Ramunas,只是说第一个对我来说可以很好地工作。我已经接受了你的回答。 - roryok
这对我没有用,ModelState 没有填充错误消息。 - Ciaran Gallagher

2

您的问题可以通过使用FluentValidation AbstractValidator.Custom 来解决:

Custom(m => String.IsNullOrEmpty(m.Username) && String.IsNullOrEmpty(m.Email)
    ? new ValidationFailure("", "Enter either a username or email address.")
    : null);

在ValidationFailure构造函数中使用空字符串确保验证消息不与任何输入字段绑定,因此它会出现在验证摘要中,例如:

ModelState.AddModelError("", "Enter either a username or email address.")

would.


这对我没用,验证消息没有出现在模型状态中。Custom方法似乎也已经过时了。我尝试使用RuleFor(x => x).Custom,但签名与您的代码不匹配。 - Ciaran Gallagher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接