非可空类型的ASP.NET MVC 5模型验证(Int32)

时间:2016-06-28 08:57:48

标签: asp.net-mvc asp.net-mvc-5 model-validation

我正在开发ASP.NET MVC 5应用程序,项目所有者担心验证不可空类型导致的“欠发布”问题(如http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.htmlhttp://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();
    }
}

似乎当帖子中data1data2为空时,模型中的值(contact)将为0.但是,ModelState.IsValid也将为 false (而不是 true ,如两篇文章所示)。

我有什么:

enter image description here

第二篇文章显示:

enter image description here

我找不到有关模型验证在ASP.NET MVC中的工作方式的任何信息,所以我猜测我的测试用例出了问题。任何想法和建议都表示赞赏。

1 个答案:

答案 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,并且您可以防止出现欠发问题。