Asp.net

嵌套 ViewModel 的驗證

  • January 18, 2013

我有兩個 ViewModel(簡化):

public class ParentViewModel
{
   public ParentViewModel
   {
       Content = new ChildViewModel();
   }

   public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
   [Required]
   public string Name1 { get; set, }
   [Required]
   public string Name2 { get; set, }
}

以及以下控制器發布操作:

[HttpPost]
public ActionResult Create(ParentViewModel viewModel)
{
   if (ModelState.IsValid)
   {
       // process viewModel -> write something into database
       return RedirectToAction("Index");
   }
   return View(viewModel);
}

現在,我將發布請求正文中的以下表單值發送到與該操作對應的 URL(在 Fiddler 請求生成器中手動):

  • 內容.名稱1=X

這工作正常,Name1屬性已填寫viewModel.Content, Name2isnull並且模型狀態無效,因為Name2是必需的。因此,驗證按預期失敗。

  • Xontent.Name1=X或Name1= X或其他任何東西都不會綁定到viewModel

現在viewModel.Content不是null(因為我在建構子中實例化它)而是所有屬性Name1Name2null. 這是意料之中的。我沒想到的是模型狀態是有效的,所以它通過了驗證(後來導致數據庫異常,因為有不可為空的列)。

如何改進此程式碼,以便驗證也適用於第二種情況?

我做了三個實驗:

  • 我已經刪除了Content建構子中的實例化ParentViewModel,然後Contentnull上面的第二個範例中,但驗證仍然通過。
  • 我已經為屬性添加了一個[Required]屬性Content(但沒有刪除建構子中的實例化ContentParentViewModel。這根本沒有影響,上面兩個測試的描述行為是相同的。
  • 我已經為屬性添加了一個屬性[Required]刪除了建構子中的實例化。這似乎可以按我的意願工作:在第二個測試中,由於該屬性,驗證失敗。它看起來像這樣:Content``Content``ParentViewModel``Content``null``[Required]
public class ParentViewModel
{
   [Required]
   public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
   [Required]
   public string Name1 { get; set, }
   [Required]
   public string Name2 { get; set, }
}

我現在可以得出結論,Content在建構子中實例化子屬性ParentViewModel是問題的根源,並且模型綁定器本身必須實例化子屬性(或者如果請求中沒有匹配的表單欄位,則不實例化)才能正確地工作伺服器端驗證。

我在其他幾個視圖模型建構子中有子屬性實例化,直到現在才注意到這個問題。那麼,這通常是一種不好的做法嗎?還有其他方法可以解決問題嗎?

第三種解決方案很好:

public class ParentViewModel
{
   [Required]
   public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
   [Required]
   public string Name1 { get; set, }
   [Required]
   public string Name2 { get; set, }
}

我現在在幾個地方使用它,沒有發現任何問題。

ModelState.IsValid 告訴您是否已將任何模型錯誤添加到 ModelState。

預設模型綁定器將為基本類型轉換問題添加一些錯誤,例如為“int”傳遞非數字。您可以根據您使用的任何驗證系統更充分地填充 ModelState。我建議查看數據註釋以驗證 ViewModel,因為它執行良好。

此語法可能錯誤或陳舊。ModelState.AddModelError(“鍵”,異常)

什麼是 ModelState.IsValid 在 NerdDinner 的 ASP.NET MVC 中有效?

引用自:https://stackoverflow.com/questions/8318465