非空类型的ASP.NET MVC 5模型验证(Int32) [英] ASP.NET MVC 5 model validation for non-nullable types (Int32)

查看:286
本文介绍了非空类型的ASP.NET MVC 5模型验证(Int32)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET MVC 5应用程序,项目所有者担心由验证非空类型(如

控制器:

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 ).

我所拥有的:

第二篇文章显示的内容:

我找不到有关ASP.NET MVC中模型验证的工作方式更改的任何信息,所以我猜想我的测试用例做错了什么.任何想法和建议都会受到赞赏.

解决方案

您的ModelState为false的原因是,该帖子提供了模型中每个属性的表单值.本质上,模型绑定系统正在检查@ Html.EditorFor helpers 明确地为视图中的两个属性编写的data1和data2字段的有效性(因此实际上没有发生发布不足的情况).

我确实成功地复制了文章中关于发布不足的问题.只需删除视图中的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>

确保对data2属性完全关闭@ Html.EditorFor帮助器.现在,在表单字段中填写零(当然,现在在视图中您将只填写一个表单字段),然后发布到您的操作中.

在这种情况下,即使仅发布一个表单字段,ModelState也将恢复为true.如果有人做卧底,那就不是一个好结果!因此,这里是(略作修改的)原始模型类,在表单字段遗漏表单的情况下,会发生发布不足的问题(请注意,由于这两个属性都是值类型,因此Required属性在这种情况下没有任何区别):

//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 Validation将返回为false,从而可以防止发布不足的问题.

I'm working on an ASP.NET MVC 5 application and the project owner is concerned about "under-posting" issues caused by validating non-nullable types (as mentioned in http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html and http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api).

I created a test case to replicate this issue in ASP.NET MVC 5 but without luck.

Model:

public class ContactModel
{
    [Required]
    public Int32 data1 { get; set; }

    public Int32 data2 { get; set; }
}

View:

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

Controller:

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

It seems that when data1 and data2 are null in the post, their values in the model (contact) will be 0. However, ModelState.IsValid will also be false (instead of true as shown in the two articles).

What I have:

What the second article showed:

I couldn't find any information regarding changes on how model validation works in ASP.NET MVC, so I'm guessing I did something wrong with my test case. Any thought and suggestion are appreciated.

解决方案

The reason your ModelState is false is because the post is providing form values from each property in your model. Essentially the Model binding system is checking the validity of both data1 and data2 fields as you have @Html.EditorFor helpers explicitly written for both properties in your view (so no underposting is actually going on).

I did successfully replicate the under-posting concerns from the articles. Simply remove one of the EditorFor helpers in your view, so you're actually underposting. With both helpers present, there's no underposting going on. So the view looks like this now (note I added the validation helper for both properties to get feedback in the view on what's going on):

View:

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

Make sure to leave the @Html.EditorFor helper completely off for the data2 property. Now fill in zero in the form field (you'll only one form field in the view of course now), and post to your action.

ModelState will come back as true in this scenario, even though only one form field is being posted. Not a good result if someone does underpost! So here's the (slightly modified) original model class where underposting issues will occur in the case a form field is left off of your form (note the Required attributes don't make any difference in this situation as both properties are value types):

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

Now the solution if you want to solve the underposting issue: Simply mark both properties as required and make them nullable as mentioned in the articles you provided, like so:

[Required]
public Int32? data1 { get; set; }

[Required]
public Int32? data2 { get; set; }

Now when the view is posted with a missing @Html.EditorFor helper or a missing form field, the ModelState Validation will come back as false, and you're protected from underposting issues.

这篇关于非空类型的ASP.NET MVC 5模型验证(Int32)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆