EmailAttribute在ASP.NET Core的ViewModel中无法正确验证

Mat*_*hew 5 c# email-validation asp.net-mvc-viewmodel asp.net-core-mvc asp.net-core

这是我的视图模型中的一个字段:

[Required(ErrorMessage = "Email is missing."), EmailAddress(ErrorMessage = "Email is not valid.")]
public string Email { get; set; }
Run Code Online (Sandbox Code Playgroud)

EmailAddress来自EmailAddressAttribute.EmailAddressAttribute()类型)
这是HTML的相关部分:

<div>
    <label for="inputEmail">EMAIL</label>
    <input id="inputEmail" ng-model="email" asp-for="Email" class="form-control" />
</div>
<div>
    <span asp-validation-for="Email" class="text-danger"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

当我myemail在电子邮件文本框中键入内容时,会说

电邮无效

但是,在键入时myemail@email,视图模型会将其视为正确的(仅在前端)。

public async Task<JsonResult> Register([FromForm]VisitViewModel vm)
Run Code Online (Sandbox Code Playgroud)

这样正确的转换会使ModelStateon无效,并拒绝电子邮件,因此该部分还可以。

但是根据此答案,前端应将此表示为无效

有人可以解释这里发生了什么吗?我绝对不知所措。

Wil*_*Ray 5

客户端和服务器之间验证电子邮件的方式不一致。

客户端

jQuery Validation使用HTML标准中定义的正则表达式。根据该表达式,email@email是一个有效的电子邮件地址。

服务器端

.Net EmailAddressAttribute具有自己的正则表达式,您可以在此处找到。根据该表达式,email@email无效的电子邮件地址。

但这变得更加令人困惑!如果您要创建.Net Core应用,则跨平台定位使用该属性的CoreFX版本,而该版本似乎根本不使用正则表达式。根据该方法,email@email是一个有效的电子邮件地址。

您可以通过在project.jsonCore Console App中切换值来自己查看:

public static void Main(string[] args)
{
    var attr = new EmailAddressAttribute();
    var email = "email@email";
    var isValid = attr.IsValid(email); // false with "net452", true with "netcoreapp1.0"
}
Run Code Online (Sandbox Code Playgroud)

你可以做什么

我能想到的最快的解决方法是更改jQuery Validate电子邮件方法中的正则表达式以匹配.Net中的正则表达式,或者创建自己的验证方法以添加到该方法中以检查此特殊情况。

您也可以回退从服务器返回的错误,这将向他们显示有关的任何错误的验证消息ModelState。这不是一个实时错误,但是他们仍然会收到一条不错的消息来处理不正确的电子邮件。