我正在开发ASP.NET MVC 5应用程序,项目所有者担心验证不可空类型导致的“欠发布”问题(如http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html和http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api中所述)。
我创建了一个测试用例,以便在ASP.NET MVC 5中复制此问题,但没有运气。
型号:
public class ContactModel
{
[Required]
public Int32 data1 { get; set; }
public Int32 data2 { get; set; }
}
查看:
<div class="form-group">
@Html.LabelFor(model => model.data1)
<div>
@Html.EditorFor(model => model.data1)
</div>
</div>
<div>
@Html.LabelFor(model => model.data2)
<div>
@Html.EditorFor(model => model.data2)
</div>
</div>
控制器:
public ActionResult Index(Models.ContactModel contact)
{
if (ModelState.IsValid)
{
Response.Write("modelstate is valid<br>");
return View();
}
else
{
Response.Write("modelstate is invalid<br>");
return View();
}
}
似乎当帖子中data1
和data2
为空时,模型中的值(contact
)将为0.但是,ModelState.IsValid也将为 false (而不是 true ,如两篇文章所示)。
我有什么:
第二篇文章显示:
我找不到有关模型验证在ASP.NET MVC中的工作方式的任何信息,所以我猜测我的测试用例出了问题。任何想法和建议都表示赞赏。
答案 0 :(得分:1)
ModelState为false的原因是因为帖子是从模型中的每个属性提供表单值。本质上,模型绑定系统正在检查data1和data2字段的有效性,因为您在视图中为两个属性编写了@Html.EditorFor帮助显式(因此实际上没有进行下调)。
我确实成功复制了文章中的欠发布问题。只需在视图中删除其中一个EditorFor帮助程序,这样您实际上就不足了。如果两位助手都在场,那么就没有任何支持。所以视图现在看起来像这样(注意我添加了两个属性的验证助手,以便在视图中获得反馈):
查看:
<div class="form-group">
@Html.LabelFor(model => model.data1)
<div>
@Html.EditorFor(model => model.data1)
@Html.ValidationMessageFor(model => model.data1)
@Html.ValidationMessageFor(model => model.data2)
</div>
</div>
确保完全关闭@ Html.EditorFor帮助程序以获取data2属性。现在在表单字段中填写零(当然,您在视图中只有一个表单字段),然后发布到您的操作中。
在此场景中,ModelState将返回true,即使只发布了一个表单字段。如果有人做不足之处,那不是一个好结果!所以这里是(略微修改过的)原始模型类,如果表单字段不在您的表单中,则会出现下层问题(请注意,必需属性不会在这种情况下作为两个属性产生任何差异值类型):
//You could add the Required attribute or not, doesn't matter at this point.
//The concern here is that the Modelstate will still come back as Valid
//in the case of a form field being left off of your form (or someone underposts).
//So to replicate underposting issues, make sure to comment or delete
//at least one Html.EditorFor helper in the view.
//[Required] Underposting will occur regardless if this is marked required or not,
//so be careful if someone does underpost your form.
public Int32 data1 { get; set; }
//[Required]
public Int32 data2 { get; set; }
现在解决方案是否要解决下层问题: 只需根据需要标记这两个属性,并按照您提供的文章中的说明使它们可以为空,如下所示:
[Required]
public Int32? data1 { get; set; }
[Required]
public Int32? data2 { get; set; }
现在,当发布的视图缺少@ Html.EditorFor帮助程序或缺少表单字段时,ModelState验证将返回false,并且您可以防止出现欠发问题。