流畅验证的电子邮件检查与服务器端不是同一个客户端

Email check by fluent validation is not the same client as serverside

我正在使用 FluentValidation 在客户端和服务器端验证我的模型。我正在使用最新版本的 :

FluentValidation.MVC5

撰写本文时,即

5.5.0.0

我有以下简化的验证器:

public class MyViewModelValidator : AbstractValidator<MyViewModel>
    {
        public MyViewModelValidator()
        {
                RuleFor(x => x.Email)
                    .EmailAddress().WithLocalizedMessage(() => MyResources.Validation_Email_NotValidAddress)
                    .NotEmpty()
                    .WithLocalizedMessage(() => MyResources.Validation_Email);
        }
    }

客户端它似乎做了一些基本的验证,比如它不会接受任何在“@”符号两边没有文本的东西,但是它会接受像 test@test.

这样的东西

当我 post 这个数据时,问题出现了,我的控制器中有以下内容:

    if (!ModelState.IsValid)
        throw new Exception("Model validation error");

由于 test@test 电子邮件地址,这将模型视为无效并抛出错误。所以看起来我的前端验证比我的服务器端验证更宽松。

参考文档后,它确实声明客户端支持 Email() 方法,但是此服务器端与呈现给前端的内容之间似乎存在一些差异。

https://fluentvalidation.codeplex.com/wikipage?title=mvc

如何通过电子邮件确保客户端验证与服务器端一样彻底。

客户端电子邮件输入规则(用data-val-email属性装饰)在jquery.validate plugin core中定义(在页面上搜索'email'字然后你找到 RegExp)

电子邮件 属性 的服务器端 规则在 Fluent Validation EmailValidator class(也是 RegExp)

中定义

就生命周期而言,这些项目没有共同之处:在任何新版本发布中,内部正则表达式可以同时在两个项目中变得 more/less 严格,如果您的目标是在客户端和服务器上使用相同的规则并使其正常工作,无论 plugin/library 版本更新——我的建议是用 Match() 规则替换当前的 EmailAddress() 规则并指定正则表达式,明确地满足你的域模型需求。

更新

选择合适的正则表达式是另一个话题,被广泛描述here

正如 Evgeny 在上面提到的,我最终选择使用 Matches 规则,因为这是客户端支持的验证器之一。

   RuleFor(x => x.Email)
                .Matches(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").WithLocalizedMessage(() => MyResources.Validation_Email_NotValidAddress)              
                .NotEmpty() // <-- and cant be empty
                .WithLocalizedMessage(() => MyResources.Validation_Email);

我相信上面的正则表达式被 ASP.NET 用于 RegularExpressionValidator。并且很适合我的要求。