代码之家  ›  专栏  ›  技术社区  ›  Çağdaş Tekin

为什么默认模型绑定器在字段不在表单数据中时不验证字段?

  •  2
  • Çağdaş Tekin  · 技术社区  · 17 年前

    假设有这样一个简单的对象:

    public class MyObject {
        public int Test { get; set; }
    }
    

    您可以使用默认的模型绑定器来确保用户在发布如下表单时不会将“测试”字段留空:

    <form method="post" action="/test">
        <p>
            <%=Html.TextBox("Test") %>
            <%=Html.ValidationMessage("Test") %>
        </p>
        <input id="Submit1" type="submit" value="submit" />
     </form>
    

    这个动作:

    [AcceptVerbs(HttpVerbs.Post)]
     public ActionResult Test(MyObject o) {
         return View();
     }
    

    当表单数据包含一个“Test”键(比如 Test=val “或” Test= ")

    但如果密钥不在表单数据中,则不会进行验证因此,如果post请求是空的,或者请求的数据类似于 AnotherField=foo 模型对象上的属性默认为类型的默认值(在本例中为0)和 ModelState.IsValid 返回true。

    在国际海事组织看来,这不是人们所期望的行为。
    那么,你建议如何改变这种行为呢?

    编辑: 请记住,恶意用户可以很容易地篡改表单数据 FireBug 或 Tamper Data 插件来传递默认模型绑定器的验证,这可能会导致一些安全问题。

    4 回复  |  直到 17 年前
        1
  •  2
  •   miha    16 年前

    不幸的是,它没有通过设计来验证字段请看一下这个 Codeplex issue 我发现并评论过。

    很不幸,MS已经决定这是他们的模型绑定器的正确行为。

    我相信默认的模型绑定器应该验证整个 实体 而不仅仅是发布的数据。

        2
  •  1
  •   48klocs    17 年前

    你可以考虑使用 xVal 执行客户端和服务器端验证的必要组合有了它,您可以向测试属性添加一个属性,该属性指示应用哪种验证规则(必需的、regex验证等),然后,再做一点工作,让它为您生成JavaScript规则,并非常容易地执行模型验证。

    你已经意识到你违反了一条开发规则——永远不要相信客户端的输入真的没办法。

    客户端验证(防止往返发现错误)很好,服务器端验证验证事情是否真正有序是必须的。

        3
  •  0
  •   Simon_Weaver    17 年前

    我希望它的设计,因为我即将开始依赖这种行为!

    在一个实例中,我有两个控件,用于回发以下字段:

    ShippingAddress.FirstName
    ShippingAddress.LastName
    ShippingAddress.Line1
    ShippingAddress.Line2
    
    BillingAddress.Email
    BillingAddress.FirstName
    BillingAddress.LastName
    BillingAddress.Line1
    BillingAddress.Line2
    

    注意:帐单地址没有显示电子邮件,尽管基础模型当然仍然显示它

    如果我的模型中有电子邮件作为[必需的]数据注释,那么它只会在帐单地址中丢失时才会抱怨。

    但我绝对明白你的意思我只是在这一个场景中依赖它!

        4
  •  0
  •   Rake36    17 年前

    在研究了将表单值输入控制器方法的所有不同方法之后,我发现“最安全”的方法是显式地将每个表单字段定义为控制器的参数一个副作用是,如果表单没有一个字段,它将抛出一个异常-这将解决您的问题。