我有兩個的ViewModels的(簡化的):驗證嵌套的ViewModels
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 Request Builder中手動):
Content.Name1 = X
這工作得很好,在
Name1
財產填充viewModel.Content
,Name2
是null
因爲Name2
需要模型的狀態是無效的。因此,驗證失敗如預期。Xontent.Name1 = X或名1 = X或任何這樣,任何被綁定到
viewModel
現在
viewModel.Content
不null
(因爲我在構造函數實例化的話),但所有物業Name1
和Name2
是null
。這是預料之中的。我所做的而不是預計模型狀態爲有效,所以它通過驗證(以後導致數據庫異常,因爲有不可空列)。
我該如何改進此代碼,以便驗證也適用於第二種情況?
我做了三個實驗:
我在
ParentViewModel
構造除去Content
實例化,然後Content
是在上面的第二個例子null
,但驗證仍然通過。我添加了一個
[Required]
屬性的Content
屬性(但並未刪除Content
的實例在ParentViewModel
構造函數)。這完全沒有影響,上述兩個測試的描述行爲是相同的。我添加了一個
[Required]
屬性的Content
財產和在ParentViewModel
構造去掉Content
的實例。這看起來像我想要的那樣工作:在第二個測試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, } }
我現在可以得出結論,在實例中ParentViewModel
構造的Content
子屬性是問題的根源和模型綁定本身必須實例子屬性(或不,如果請求中沒有匹配的表單字段),以便具有正確工作的服務器端驗證。
我有幾個其他視圖模型構造函數中的子屬性實例,並沒有注意到這個問題,直到現在。所以,這通常是一種不好的做法?還有其他方法可以解決問題嗎?
我目前正在努力與類似的東西。我的情況只有差異,我有一個ChildViewModels的IEnumerable。我已經嘗試了上面的所有三個選項,似乎沒有任何工作適合我。 –