我有两个 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);
}
现在,我将 post 请求正文中的以下表单值发送到与该操作对应的 URL(在 Fiddler 请求生成器中手动):
-
内容.Name1=X
这工作正常,Name1
属性已填写viewModel.Content
, Name2
is null
并且模型状态无效,因为Name2
是必须的。因此,验证按预期失败。
-
内容.名称 1=X or Name1=X或其他任何东西,这样就没有任何东西可以绑定到viewModel
Now viewModel.Content
is not null
(因为我在构造函数中实例化它)但所有属性Name1
and Name2
are null
。这是预料之中的。我做了什么not期望模型状态是valid,因此它通过了验证(稍后会导致数据库异常,因为存在不可为空的列)。
如何改进此代码,以便验证在第二种情况下也能正常工作?
我做了三个实验:
我已经删除了实例化Content
in the ParentViewModel
构造函数,那么Content
is null
在上面的第二个示例中,但验证仍然通过。
我添加了一个[Required]
归因于Content
属性(但没有删除Content
in the ParentViewModel
构造函数)。这根本没有影响,上面两个测试所描述的行为是相同的。
-
我添加了一个[Required]
归因于Content
财产and删除了实例化Content
in the ParentViewModel
构造函数。这似乎按我想要的方式工作:在第二个测试中Content
is 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
构造函数是问题的根源,并且模型绑定器本身必须实例化子属性(如果请求中没有匹配的表单字段,则必须实例化子属性)才能正常工作的服务器端验证。
我在其他几个视图模型构造函数中都有子属性实例化,直到现在才注意到这个问题。那么,这通常是一种不好的做法吗?还有其他方法可以解决这个问题吗?
ModelState.IsValid 告诉您是否有任何模型错误已添加到 ModelState。
默认模型绑定器将为基本类型转换问题添加一些错误,例如为“int”传递非数字。您可以根据您使用的任何验证系统更全面地填充 ModelState。我建议研究数据注释来验证 ViewModel,因为它运行良好。
此语法可能是错误的或旧的。 ModelState.AddModelError("key", 异常)
转述自ModelState.IsValid 在 NerdDinner 的 ASP.NET MVC 中有效吗? https://stackoverflow.com/questions/881281/what-is-modelstate-isvalid-valid-for-in-asp-net-mvc-in-nerddinner
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)