我有两个的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。我已经尝试了上面的所有三个选项,似乎没有任何工作适合我。 –