Asp.net mvc 不可为空类型的ASP.NET MVC 5模型验证(Int32)
我正在开发一个ASP.NET MVC 5应用程序,项目负责人担心由于验证不可为null的类型(如和中所述)而导致的“发布不足”问题 我创建了一个测试用例来在ASP.NETMVC5中复制这个问题,但运气不好 型号:Asp.net mvc 不可为空类型的ASP.NET MVC 5模型验证(Int32),asp.net-mvc,asp.net-mvc-5,model-validation,Asp.net Mvc,Asp.net Mvc 5,Model Validation,我正在开发一个ASP.NET MVC 5应用程序,项目负责人担心由于验证不可为null的类型(如和中所述)而导致的“发布不足”问题 我创建了一个测试用例来在ASP.NETMVC5中复制这个问题,但运气不好 型号: public class ContactModel { [Required] public Int32 data1 { get; set; } public Int32 data2 { get; set; } } 视图: @LabelFor(model=>
public class ContactModel
{
[Required]
public Int32 data1 { get; set; }
public Int32 data2 { get; set; }
}
视图:
@LabelFor(model=>model.data1)
@EditorFor(model=>model.data1)
@LabelFor(model=>model.data2)
@EditorFor(model=>model.data2)
控制器:
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();
}
}
public ActionResult索引(Models.ContactModel联系人)
{
if(ModelState.IsValid)
{
Write(“modelstate有效
”;
返回视图();
}
其他的
{
Write(“modelstate无效
”;
返回视图();
}
}
似乎当post中的data1
和data2
为空时,它们在模型(contact
)中的值将为0。但是,ModelState.IsValid也将是false(而不是两篇文章中显示的true)
我所拥有的:
第二篇文章显示:
我找不到任何关于ASP.NET MVC中模型验证工作方式变化的信息,所以我猜我的测试用例出了问题。感谢您的任何想法和建议。您的模型状态为false的原因是因为帖子提供了模型中每个属性的表单值。本质上,模型绑定系统正在检查data1和data2字段的有效性,就像您在视图中为这两个属性显式编写的@Html.EditorFor helpers一样(因此实际上没有进行底版) 我确实成功地复制了文章中发布不足的问题。只需在视图中删除其中一个EditorFor helpers,那么您实际上是在降低成本。由于两名助手都在场,因此没有进行任何隐藏。因此,视图现在看起来是这样的(注意,我为这两个属性添加了validation helper,以便在视图中获得关于发生了什么的反馈): 视图: 现在,如果要解决底价问题,请选择以下解决方案: 只需根据需要标记这两个属性,并按照您提供的文章中所述使其为空,如下所示:
[Required]
public Int32? data1 { get; set; }
[Required]
public Int32? data2 { get; set; }
现在,当使用缺少的@Html.EditorFor helper或缺少的表单字段发布视图时,ModelState验证将返回为false,并且您可以避免隐藏不足的问题。您不需要
int
属性上的[必需]
属性(除非您需要自定义错误消息)-一个int
不能是null
。DefaultModelBinder
添加了一个错误,因为您无法将null
分配给int
并设置ModelState.IsValid=false
。但是这个值是0
,因为这是int
@StephenMuecke的默认值,这是我最初的想法。但是根据Brad Wilson的帖子(我问题中的第一个链接):这个问题的出发点是,不可为null的值类型上的[Required]不能保证表单包含值。如果不包含值,则跳过模型绑定,这意味着不会发生模型绑定失败。此外,当[Required]验证器运行时,它从模型中查询值——其中将包含值类型默认值,通常为0——并说“这不是null,这里一切都好!”。这是错误的,并且永远不会跳过模型绑定<如果为具有[必需]
属性的值类型或引用类型的属性发送值,则code>ModelState.IsValid将始终为false如果要对整数类型进行验证,[必需]
属性在此特定场景中无效。正如文章所说:这是否是一个问题取决于您的场景。因此,如果您希望对整数类型进行验证,我建议使用[Range]
验证属性,因为它在这种情况下更有意义。谢谢!这听起来确实很有希望。今天晚些时候我会尝试复制这个,如果它有效的话,我会为答案打分。太棒了,吉姆。我通过调试器运行它并验证了行为,所以一切都应该正常。如果你有任何问题,请告诉我。顺便说一句,我很高兴我遇到了你的问题。该必需属性可能会产生误导,如果不小心,您可能会突然将属性设置为其默认值。谢谢,蒂姆
<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>
//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; }