Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 不可为空类型的ASP.NET MVC 5模型验证(Int32)_Asp.net Mvc_Asp.net Mvc 5_Model Validation - Fatal编程技术网

Asp.net mvc 不可为空类型的ASP.NET MVC 5模型验证(Int32)

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=>

我正在开发一个ASP.NET MVC 5应用程序,项目负责人担心由于验证不可为null的类型(如和中所述)而导致的“发布不足”问题

我创建了一个测试用例来在ASP.NETMVC5中复制这个问题,但运气不好

型号:

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; }