1

我试图使用Data Annotations,jQuery ValidationjQuery Unobtrusive validation验证Asp.net Core 2.0应用程序中的HTML表单,正如文档强烈建议的那样。我也有一些自定义的Javascript来在通知窗口中显示错误消息。如何在Asp.net Core 2中使用jQuery获取已翻译的ModelState错误消息?

我有一个模型,看起来像这样:

class Model 
{ 
    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Email")] 
    [EmailAddress(ErrorMessage = "ValidEmail")] 
    public string Email { get; set; } 
} 

多次尝试后,我得到了Asp.net发出的input标签准备验证,在正确的本地化错误消息:

<input class="form-control input-validation-error" type="email" 
    data-val="true" data-val-email="L'adresse e-mail est invalide." 
    data-val-required="Le champ E-mail est obligatoire." id="Email" 
    name="Email" value="[email protected]" aria-describedby="Email-error"> 

我已成功地在提交表单之前获得了客户端验证,。 jQuery验证正确检测到一个空字段,我可以使用Javascript显示来自data-val-required的消息。为了完整起见,我有这样的事情处理的消息:

function onFormValidationFailed(e, args: JQueryValidation.Validator) { 
    ErrorManager.clearErrors(); 

    for (var error in args.errorList) { 
     ErrorManager.addError(args.errorList[error].message); 
    } 
} 

$("form") 
    .on("invalid-form.validate", onFormValidationFailed); 

然而,如[email protected]一个值由客户端验证接受等形式提交。该错误然后被Asp.net模型验证捕获。在我的行动中,我可以看到this.ModelState.IsValid确实是false,正如您在上面所看到的,该字段被正确识别为与类input-validation-error有差错。

我的问题是,我不知道如何获得相关的错误信息来显示它。

我试图调用$("form").validate()当页面加载试图触发验证,但我没有收到任何错误消息。 (或至少invalid-form.validate事件没有被触发。)

作为备用解决方案,我尝试使用<div asp-validation-summary="All"></div>让Asp.net将错误消息注入某个地方,我可以使用Javascript获取它们。但是这很快就变成了一个死胡同,因为这条消息没有被本地化!

<div class="validation-summary-errors" data-valmsg-summary="true"> 
    <ul> 
     <li>ValidEmail</li> 
    </ul> 
</div> 

事实上,我检查了服务器端和ModelState收集不包含本地化的消息。

谁能帮我找到一个解决方案,其中,在与一个无效的模型状态来从服务器返回的,我可以得到的,通过JavaScript,相关本地化数据注解的错误信息,所以我可以将它们显示给用户? (或建议更好的做法?)

回答

0

我找到了我的问题的答案,虽然有点尴尬,但我在这里分享它,以防其他人发现自己处于类似的情况。

实际问题

原来我工作的代码是不完全像上面描述的,但我没有注意到,直到我试图创建一个精简版本重现。

模型看上去很是这样的:

class Model : ModelData 
{ 
} 

class ModelData 
{ 
    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Email")] 
    [EmailAddress(ErrorMessage = "ValidEmail")] 
    public string Email { get; set; } 
} 

的看法有这样的代码:

@model MyApp.Model 

<input asp-for="Email" /> 

而且控制器,有这样几个方法:

[HttpGet] 
public IActionResult Edit() 
{ 
    return View(new Model()); 
} 

[HttpPost] 
public IActionResult Edit(ModelData data) 
{ 
    if (ModelState.IsValid) 
    { 
     data = _service.Save(data); 
    } 

    var model = new Model 
    { 
     Email = data.Email 
    }; 

    return View(model); 
} 

我的resx文件被称为Model.resx

根本原因

我错过了模型中的继承!

一旦我发现,一切是有意义的:

  • 在构建视图,型号,类型的Model发现译文Model.resx
  • 当行动验证虽然,验证类型为无ModelData和资源管理器无法找到翻译那种类型,因为没有ModelData.resx

的修复

我做了什么来解决我的问题是prefer composition over inheritance。我的模型现在看起来是这样的:

class Model 
{ 
    public ModelData Data { get; set; } 
} 

这样的观点:

@model MyApp.Model 

<input asp-for="Data.Email" /> 

而且感动了所有相关的翻译到ModelData.resx。由于ModelData是我正在建造的类型input s对于在控制器操作中进行验证,所以始终正确处理资源。