Asp.net-Mvc
ModelState.IsValid 還是 Model.IsValid?
當我遇到兩種方法(我認為同樣有效)來做某事時,我正在為它編寫一個控制器和單元測試。我所有的模型都有一個 IsValid 屬性,我可以檢查它以詢問模型是否有效。
在回發到控制器操作方法時,如果模型有效,我想保存,否則我想重新顯示表單以供使用者糾正錯誤。
我最初的想法是驗證模型是否被詢問是否有效,但我意識到我也可以檢查 ModelState.IsValid。
有沒有人有任何特別的理由來看待一個與另一個?
我認為將自定義業務驗證內置到您的模型中是一種很好的方法。我處理它的方法是將任何自定義驗證錯誤添加到 ModelState:
if (ModelState.IsValid) { if (!model.IsValid) { ModelState.AddModelError("The model is not valid"); } else { return RedirectToAction("Index"); } } return View(model);這樣,您的視圖就可以訪問驗證錯誤,無論它們是自定義的還是內置的。
ModelState可以轉移到TempData跟隨Post-Redirect-Get。例子:[HttpPost] [ExportModelStateToTempData] public ActionResult Delete(int id) { if (_service.DeleteTask(id)) return RedirectToAction(ControllerActions.Index); return RedirectToAction(ControllerActions.Edit, new { id }); } [ImportModelStateFromTempData] public ActionResult Edit(int id) { var task = _service.GetTask(id); return View(ControllerActions.Edit, GetEditModel(task)); }使用者可以通過 callig /Task/Delete 操作刪除任務,但如果出現問題並出現錯誤消息,按 F5 將不會再次呼叫刪除。當
ModelStateafterDelete轉移到時Edit,所有錯誤都顯示在編輯頁面上。這是屬性導入/導出的程式碼
ModelState:public abstract class ModelStateTempDataTransferAttribute : ActionFilterAttribute { protected static readonly string Key = typeof(ModelStateTempDataTransferAttribute).FullName; } public class ExportModelStateToTempDataAttribute : ModelStateTempDataTransferAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { //Only export when ModelState is not valid if (!filterContext.Controller.ViewData.ModelState.IsValid) { //Export if we are redirecting if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult)) { filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState; } } base.OnActionExecuted(filterContext); } } public class ImportModelStateFromTempDataAttribute : ModelStateTempDataTransferAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary; if (modelState != null) { //Only Import if we are viewing if (filterContext.Result is ViewResult) { filterContext.Controller.ViewData.ModelState.Merge(modelState); } else { //Otherwise remove it. filterContext.Controller.TempData.Remove(Key); } } base.OnActionExecuted(filterContext); } }做同樣的
Model事情會很成問題。