代码之家  ›  专栏  ›  技术社区  ›  Will

需要使用嵌套模型的DefaultModelBinder的帮助

  •  3
  • Will  · 技术社区  · 14 年前

    有几个相关的问题,但我找不到有效的答案。

    假设我有以下模型:

    public class EditorViewModel
    {
      public Account Account {get;set;}
      public string SomeSimpleStuff {get;set;}
    }
    
    public class Account
    {
      public string AccountName {get;set;}
      public int MorePrimitivesFollow {get;set;}
    }
    

    以及延伸 ViewPage<EditorViewModel> 执行以下操作:

    <%= Html.TextBoxFor(model => model.Account.AccountName)%>
    <%= Html.ValidationMessageFor(model => model.Account.AccountName)%>
    <%= Html.TextBoxFor(model => model.SomeSimpleStuff )%>
    <%= Html.ValidationMessageFor(model => model.SomeSimpleStuff )%>
    

    我的控制器看起来像:

    [HttpPost]
    public virtual ActionResult Edit(EditorViewModel account)
    { /*...*/ }
    

    如何使DefaultModelBinder正确绑定我的EditorViewModel?没有做任何特殊的事情,我得到了一个空的editorviewmodel实例,其所有内容都为空或默认值。

    我最近来的是打电话 UpdateModel 手动:

    [HttpPost]
    public virtual ActionResult Edit(EditorViewModel account)
    {
        account.Account = new Account();
        UpdateModel(account.Account, "Account");
        // this kills me:
        UpdateModel(account);
    

    这成功地更新了我的帐户属性模型,但当我在上调用UpdateModel时 account (为了得到我的编辑视图模型的其余公共属性)我得到了完全无用的“类型的模型…无法更新。“没有内部异常,所以我不知道出了什么问题。

    我该怎么办?

    1 回复  |  直到 14 年前
        1
  •  4
  •   Levi    14 年前

    绑定器变得很混乱,因为它看到了action方法的参数是命名的 解释 ,它将看到名为 帐户.帐户名 ,因此它在您的editorviewModel上查找accountname属性。

    您可以通过将参数重命名为与传入表单字段不冲突的其他内容来解决此问题,或者可以在参数上粘贴[bind(prefix=“)]属性。该属性表示“忽略参数被命名的事实 解释 然后假装我给了它一个空字符串名。 帐户.帐户名 而不是 帐户.帐户.帐户名 .

    编辑-更多信息:

    当绑定器看到名为 ,它查看当前对任何名为*foo.*的请求。所以如果参数是命名的 它的类型有一个名为 名字 ,传入值应为 foo.firstname=约翰 例如。

    但是,如果活页夹没有将*foo.*作为请求的一部分,那么它只是直接查找* 前缀)。只要请求中没有*foo.*,就可以提交 名字=约翰 活页夹会正确理解这一点。但如果请求中有任何*foo.**,则 名字=约翰 值与firstname属性不匹配。

    现在您可以看到,将参数赋给动作方法的名称与它的一个属性的名称相同将如何抛出这个逻辑。