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對於在控制器操作中進行驗證,所以始終正確處理資源。