2011-02-16 24 views
10

我正在爲它編寫一個控制器和單元測試,當我遇到兩種方式(我認爲同樣有效)做某事。我所有的模型都有一個IsValid屬性,我可以檢查該模型是否有效。ModelState.IsValid或Model.IsValid?

回發到控制器操作方法,如果模型是有效的,我想保存,否則我想重新顯示用戶的表單以糾正它們的錯誤。

我最初的想法是驗證模型是否被問及是否有效,但我意識到我也可以檢查ModelState.IsValid。

有沒有人有任何特別的理由來看待其中一個?

回答

11

我認爲在您的模型中內置自定義業務驗證是一種很好的方法。我會處理這件事的方式是任何自定義驗證錯誤添加到ModelState中:

if (ModelState.IsValid) 
{ 
    if (!model.IsValid) 
    { 
     ModelState.AddModelError("The model is not valid"); 
    } 
    else 
    { 
     return RedirectToAction("Index"); 
    } 
} 

return View(model); 

這樣,你的觀點有訪問驗證錯誤,無論它們是否是自定義或內置

6

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 /任務任務/刪除的行爲,但如果出現錯誤,錯誤消息出現時,按F5就不會再打電話刪除。當Delete之後的ModelState轉移到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將是非常有問題的。

+0

你是什麼`ControllerActions`類?這對我來說是新的。 – 2011-02-16 01:24:39

0

您還可以枚舉錯誤集合並將Exact錯誤消息寫入輸出。

else if (!ModelState.IsValid) 
{ 
    List<ModelError> modelErrors = new List<ModelError>(); 
    ModelErrorCollection errors = new ModelErrorCollection(); 
           ; 
    // got to the model and look at the Array of Values 
    foreach (var item in ModelState) 
    { 
     if (item.Value.Errors.Count != 0) 
     { 
      // get the error 
      errors = item.Value.Errors; 
      modelErrors.Add(errors.Single()); 
     } 
    } 

    if (modelErrors.Count != 0) 
    { 
     foreach (var error in modelErrors) 
     { 
      Debug.WriteLine(error.ErrorMessage); 
     } 
     } 

...