關於 ModelState.Clear()
今天再設計一個表單,存檔的時候我需要驗證資料是否有重複,
如果重複的話我要把錯誤訊息丟回前端顯示在畫面上,
原本的作法,在ViewModel裡面訂一個ErrorMessage
public class AP0010_ConitionModel
{
public String APID{get;set;}
public String ErrorMessage { get; set; }
}
然後在前端將這個物件用hidden的欄位儲存起來
<div class="form-group" style="">
<div class="col-md-2">
<button type="button" id="btnADD" class="btn btn-success">新增業務系統</button>
</div>
<label id="lblErrorMessage" class="text-danger control-label col-md-5" style="text-align:left"></label>
@Html.HiddenFor(p => p.condition.ErrorMessage, new { id = "hidErrorMessage" })
</div>
然後再程式初始化的時候用JS去把hidden裡面的值塞到label裡面
$(function(){
$('#lblErrorMessage').text($('#hidErrorMessage').val());
});
這樣程式初始化的時候,欄位會是空的,POST到後端去檢查有錯誤訊息的時候,
將錯誤訊息丟到hidErrMessage,錯誤訊息就會顯示出來,
但是實際在測試的時候發現結果不如我預期,錯誤訊息一直丟不回前端,
中斷點下在後端 也確定model.ErrorMessage 已經有我要顯示的錯誤訊息,
查了以後才發現要在下一個指令:ModelState.Clear() 如下:
[HttpPost]
public ActionResult TestAction(AP0010ViewModel model)
{
AP0010ViewModel _returnModel = model; //保留畫面上的輸入資料。
if("存檔過程錯誤")
{
_returnModel.ErrorMessage = "錯誤訊息";
}
ModelState.Clear();
return View(_returnModel);
}
我的理解是,ModelBinding 這個機制預設會保留畫面上POST到後端的資料,
當你要return 回前端的時候,會幫你把舊有的資料再顯示在畫面上
如果你沒有下這個指令,return回前端的model內的ErrorMessage就永遠是空的(也就是前端第一次POST到後端的值)
後來跟同事討論一下,其實也不用那麼麻煩,我只要把錯誤的訊息內容丟到TempData,前端直接顯示就好
Controller:
TempData["ErrorMessage"] = "要顯示的錯誤訊息";
View:
<label id="lblErrorMessage" class="text-danger control-label col-md-5" style="text-align:left">@TempData["ErrorMessage"]</label>
這樣就可以直接一次性地顯示錯誤訊息,
以上,打完收工。