ASP.NET MVC ModelState AddModelError
2024-01-04
筆記 ASP.NET 開發使用 ModelState
的方式加入 ErrorMessage,並且使用 logic filter 的技巧在 Controller,不需要大改程式碼流程就可以加入新的邏輯。
說明
原本的商務邏輯,想要增加檢查傳入的 model,如果允許才繼續進入 db.SaveChanges()
。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "...")] Website website)
{
if (ModelState.IsValid)
{
website.EditDateTime = DateTime.Now;
db.Website.Add(website);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(website);
}
因為專案的架構簡單,沒有特別拆服務層 (Service Layer) 出來,所以在負責 Present 的 Controller 處理商務邏輯的檢查。
但為了避免單一 Action 過於龐大,所以在相同的 Controller 下加入新的 NonAction
Action。
並且透過 ModelState.AddModelError
來對特定的模型屬性 (Model Property) 來加上錯誤訊息,之後就可以搭配 Unobtrusive.Validation
顯示給使用者。
[NonAction]
private bool CheckBusinessLogicValid(Website website)
{
bool businessLogic1 = true;
bool businessLogic2 = true;
if (conditionMatch)
{
businessLogic1 = false;
ModelState.AddModelError("ModelPropertyName", "Not match condition 1️⃣");
}
if (conditionMatch)
{
businessLogic1 = false;
ModelState.AddModelError("ModelPropertyName", "Not match condition 2️⃣");
}
return businessLogic1 && businessLogic2;
}
接著在原本的 Action 當中呼叫新加入的 Action 並且結合原本的 ModelState.IsValid
交集檢查符合即可。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "...")] Website website)
{
bool businessLogic = CheckBusinessLogicValid(website3);
if (ModelState.IsValid && businessLogic)
{
website.EditDateTime = DateTime.Now;
db.Website.Add(website);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(website);
}
在 View 的部分,如果,指定的 PropertyName 是存在於模型當中,則不需要特別調整,原本的 Html.ValidationMessageFor
就有能力進行處理。
@Html.ValidationMessageFor(model => model.Owner, "", new { @class = "text-danger" })
如果是刻意指定的 PropertyName 則可以透過 @Html.ValidationMessage
來顯示。
@Html.ValidationMessage("CustomPropertyName", new { @class = "text-danger" })