在ASP.NET MVC中,我們說下關于使用ModelState 的幾個技巧,它可以拓寬我們應用的視野,使用代碼更加的簡潔有效。
關于ModelState 的使用,很多是停留在Control Action 綁定模型的有效性驗證 ,包括 輸入驗證 (Input Validation) 與 模型驗證 (Model Validation) 是否成功。
例如:
if(!ModelState.IsValid)
{
return …
}
我們再深入學習下。
一.定義
將模型綁定的狀態、值封裝到 action-method 參數的屬性或參數本身。
二. 應用
- 通過ModelState,我們可以在Controller–Action 或者 View 中獲取模型綁定過程中的「驗證失敗的錯誤訊息」和 「模型綁定過程中得到的資料」。
- 有時 Model Binding 的資料並沒有從 Controller 中透過強型別的 Model 傳給 View 使用,我們經常使用 ViewBag , ViewDate等,其實我們也可以直接在View中取得 ModelState 的內容,使代碼更加簡潔有效。
- 我們也可以通過 ModelState.AddModelError(_key, _keyValue)自定義錯誤訊息。
一個登錄頁面的例子:
界面:
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">用戶登入 </p>
<div class="row">
<div class="col-xs-12">
<div asp-validation-summary="All" class="text-danger"></div>
</div>/*這里顯示ModelState的錯誤信息,如果有*/
</div>
<form asp-controller="Account" asp-action="Login" method="post">
<div class="input-group mb-3">
<input asp-for="UserName" type="text" class="form-control" placeholder="用戶名稱">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-user"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input asp-for="Password" type="password" class="form-control" placeholder="密碼" autocomplete="off">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-8">
</div>
<!-- /.col -->
<div class="col-4">
<button type="submit" class="btn btn-primary btn-block">登入</button>
</div>
<!-- /.col -->
</div>
<div class="row">
<div class="col-12">
<p></p>
<p class="text-center">
為保安理由,請輸入正確用戶名稱及密碼。
</p>
</div>
</div>
</form>
</div>
</div>
后臺Controller—Action
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel vm, string returnUrl = null)
{
//模型綁定合法驗證,通常應用
if (!ModelState.IsValid)
{
return View(vm);
}
var result = _security.SignInAsync(vm.UserName, vm.Password).GetAwaiter().GetResult();
//如果登錄信息不成功,則自定義增加一個錯誤信息,返回登錄頁面
if (result != SignInResultEnum.Succeeded)
{
ModelState.AddModelError(“LoginError”, "所輸入的用戶名稱或密碼不正確!請重新輸入。");
return View(vm);//注意:這里vm保存著頁面傳過來的用戶名,密碼;如果 改為 return View(); 效果也是一樣,因為 頁面會從ModelState 中獲取用戶名信息。即在頁面中仍會顯示 用戶名的錄入資料
}
//還可以根據需要增加其他的驗證,不通過就增加一個自定義錯誤并返回頁面
....
//最后,登錄成功,轉向系統開始頁面
return RedirectToAction("Index");
}
返回錯誤的信息
以上就是一個使用ModelState的例子
三.擴展
1. 清除ModelState的內容
清除所有已經儲存在 ModelState 裡面的內容ModelState.Clear() (包含錯誤訊息與模型綁定的資料 都會被清空);如果只想清除特定一個欄位的內容 (包含錯誤訊息與模型綁定的資料),例如使用 ModelState.Remove(“UserName”)清除 UserName的內容。
2. 在Controller – Action 或者 View頁面獲取ModelState的信息
ModelState 可以透過枚舉的方式取得每一個欄位的內容,然後用 ModelState.IsValidField 查出該欄位是否有驗證錯誤的狀態,再透過一個 foreach 迴圈取得所有該欄位 ModelState 的所有錯誤(可以有多個錯誤),最後在取得 err.ErrorMessage 得知錯誤訊息的確切內容或 err.Exception 取得該模型的例外狀況物件 (如果有)。
也可以通過 RawValue (透過 Model Binder 轉型後的值) 或 AttemptedValue (將值轉換成可顯示的字串值) 屬性內容。 例如 在View 中取得 ModelState 的相關資料。
<h5>User 的值@ViewData.ModelState ["UserName"].Value.AttemptedValue </h5>
<完>