EmailAddress DataAnnotation 在 View 上标记为有效但 ModelState.IsValid = false?
Posted
技术标签:
【中文标题】EmailAddress DataAnnotation 在 View 上标记为有效但 ModelState.IsValid = false?【英文标题】:EmailAddress DataAnnotation marking as valid on View but ModelState.IsValid = false? 【发布时间】:2017-09-16 12:10:52 【问题描述】:我正在使用 MVC5 并尝试验证表单。
当我在字段中插入无效的电子邮件地址时,它会显示错误消息
如果我插入 a@a(这是一个有效的电子邮件地址),则前端验证通过,但在后端,我的 ModelState 在 E-mail 字段中显示错误,说明这是无效的。
如果我插入 a@a.com,验证双方都会通过!
注意:与“电子邮件验证不适用于 MVC”相关的其他 SO 答案的很大一部分,解决方案是使用我已经在使用的 EmailAddress 属性。
查看
@using (Ajax.BeginForm("EnviarMensagemContato", "home", new AjaxOptions HttpMethod = "POST", OnBegin = "showLoading", OnComplete = "showJsonModalMessage" , new @id = "contact-form" ))
@html.AntiForgeryToken()
<div class="col-md-6 lateral-division">
<div class="form-group">
@Html.TextBoxFor(m => m.ContatoViewModel.Nome, new @class = "form-control required", placeholder = "nome" )
@Html.ValidationMessageFor(m => m.ContatoViewModel.Nome)
</div>
<div class="form-group">
@Html.TextBoxFor(m => m.ContatoViewModel.EmailAddress, new @class = "form-control required", placeholder = "email" )
@Html.ValidationMessageFor(m => m.ContatoViewModel.EmailAddress)
</div>
<div class="form-group">
@Html.TextAreaFor(m => m.ContatoViewModel.Mensagem, 4, 4, new @class = "form-control required", placeholder = "mensagem" )
@Html.ValidationMessageFor(m => m.ContatoViewModel.Mensagem)
</div>
</div>
<div class="btn-group pull-right btn-send-message">
<input type="submit" value="enviar" id="enviar-mensagem" class="btn btn-default" />
</div>
型号
public class ContatoViewModel
[Required(ErrorMessage="campo obrigatório"),
Display(Name = "nome")]
public String Nome get; set;
[Required(ErrorMessage = "campo obrigatório"),
Display(Name = "nome"), MaxLength(254,ErrorMessage="email inválido"),
EmailAddress(ErrorMessage="email inválido")]
public String EmailAddress get; set;
[Required(ErrorMessage = "campo obrigatório"),
Display(Name = "nome"), MaxLength(500, ErrorMessage = "maximo de 500 caracteres")]
public String Mensagem get; set;
控制器
public JsonResult EnviarMensagemContato(ModelContainer model)
try
if (ModelState.IsValid)
//zalgo
【问题讨论】:
您的视图模型似乎没有 EmailAddress 属性。 @qamar 它有,但 asp.net 出于某种原因将数据注释连接在一行中,即:[required(..), maxlength(..)]
而不是单独的行。它在代码上。问候”
a@a
不是有效的电子邮件地址。作为旁注,您可以看到属性 here 使用的正则表达式
【参考方案1】:
我假设您在 ASP.NET MVC 项目中使用默认的 jQuery Validation 库。如果是这种情况,问题就在于用于验证电子邮件的正则表达式在 jQuery Validation 库和 EmailAddressAttribute
中不同,属性更严格。我的建议是覆盖 jQuery Validation 电子邮件方法,如下所示:
$.validator.methods.email = function (value, element)
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`\|~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`\|~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/.test(value);
正则表达式直接取自EmailAddressAttribute 源代码here。如果您更喜欢允许不带 TLD 的电子邮件(例如 user@localhost),您可以编写自己的属性,如 in this answer 讨论的那样,并从 jQuery Validation 库中放入正则表达式。这样,您将拥有相同的验证结果客户端和服务器端。
【讨论】:
【参考方案2】: [Required(ErrorMessage = "The Email address is required")]
[RegularExpression(RegularExpression.RegexEmail, ErrorMessage = "Invalid Email address")]
public string Email get; set;
在 RegularExpression.cs 文件中包含
/// <summary>
/// Regular expression for email
/// </summary>
public const string RegexEmail = @"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]2,4";
【讨论】:
【参考方案3】:我不认为 a@a 是一个有效的电子邮件地址,或者如果是,我认为属性不会考虑它。
经过测试,如果我输入 a@a,我会收到客户端验证错误。我不输入 a@a.a
如果您需要此类电子邮件有效,您可以使用自己的正则表达式。
【讨论】:
【参考方案4】:如果您需要细粒度的控制并让您的代码在您面前透明,我建议您不要依赖 HTML 助手来绘制您的控件并为您在客户端和服务器端执行验证。
我将使用以下常规 exp 作为 mvc 模型属性。
[Required]
[RegularExpression(BusinessRules.Email,ErrorMessage = Messages.EmailNotValid)]
public string LoginEmail get; set;
BusinessRules.Email 在哪里
public const string Email = "^[\\w!#$%&'*+\\-/=?\\^_`|~]+(\\.[\\w!#$%&'*+\\-/=?\\^_`|~]+)*@((([\\-\\w]+\\.)+[a-zA-Z]2,4)|(([0-9]1,3\\.)3[0-9]1,3))$";
在客户端验证中,您只能根据需要确保电子邮件不为空。最后,客户端验证不如服务器端验证重要,因为它很容易被欺骗。
【讨论】:
【参考方案5】:像下面的代码一样一次表示一个数据注释是一种很好的做法,这也可能有助于解决您的错误。
[Required(ErrorMessage="campo obrigatório")]
[Display(Name = "nome")]
public String Nome get; set;
【讨论】:
【参考方案6】:有两个独立的控制点。如果您使用正确的比较一次,则不必再次检查该值以供以后使用。然后,使用正则表达式将解决问题。
【讨论】:
以上是关于EmailAddress DataAnnotation 在 View 上标记为有效但 ModelState.IsValid = false?的主要内容,如果未能解决你的问题,请参考以下文章
Validator EmailAddress可以验证一组电子邮件
获取 r_liteprofile 和 r_emailaddress - api.linkedin.com/v2
Django REST EmailAddress 匹配查询不存在
nameid-format:emailAddress 在使用电子邮件作为 nameid 格式时使用。当使用用户名作为 namid 字段时,正确的 nameid 格式是啥
urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress 是有效的 NameID 格式吗?