Sla*_*uma 8 asp.net validation asp.net-mvc asp.net-mvc-3
我有两个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, }
}
Run Code Online (Sandbox Code Playgroud)
以下控制器发布动作:
[HttpPost]
public ActionResult Create(ParentViewModel viewModel)
{
if (ModelState.IsValid)
{
// process viewModel -> write something into database
return RedirectToAction("Index");
}
return View(viewModel);
}
Run Code Online (Sandbox Code Playgroud)
现在我将后续请求正文中的以下表单值发送到与该操作对应的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.这是预料之中的.我也没有想到的是,模型的状态是有效的,所以它通过验证(导致数据库异常后,因为有非空列).
如何改进此代码以便验证在第二种情况下也适用?
我做了三个实验:
我已删除的实例化的Content在ParentViewModel构造函数中,则Content是null在第二示例中的上方,但验证仍然通过.
我添加了一个[Required]属性的Content属性(但没有删除的实例化Content的ParentViewModel构造函数).这完全没有效果,上述两个测试的描述行为是相同的.
我添加了一个[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, }
}
Run Code Online (Sandbox Code Playgroud)我现在得出结论,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, }
}
Run Code Online (Sandbox Code Playgroud)
我现在在几个地方使用它,没有发现任何问题。
| 归档时间: |
|
| 查看次数: |
4023 次 |
| 最近记录: |