使用ASP.Net MVC中的模型绑定器更新父/子记录

时间:2009-07-09 12:35:00

标签: asp.net-mvc modelbinders master-detail

我修改了Nerd Dinner应用程序以允许通过将以下代码添加到DinnerForm.ascx来编辑子记录

  <p>
    <%int i = 0;
   foreach (NerdDinner.Models.RSVP rsvp in this.Model.Dinner.RSVPs)
       { %>

        <%= Html.Hidden("Dinner.RSVPs[" + i + "].RsvpID", rsvp.RsvpID)%>
        <%= Html.Hidden("Dinner.RSVPs[" + i + "].DinnerID", rsvp.DinnerID)%>
        <%= Html.TextBox("Dinner.RSVPs[" + i + "].AttendeeName", rsvp.AttendeeName)%>
    <% i += 1;
   } %>
    </p>

它呈现了这个:

<p>
    <input id="Dinner_RSVPs[0]_RsvpID" name="Dinner.RSVPs[0].RsvpID" type="hidden" value="36" />
        <input id="Dinner_RSVPs[0]_DinnerID" name="Dinner.RSVPs[0].DinnerID" type="hidden" value="63" />
        <input id="Dinner_RSVPs[0]_AttendeeName" name="Dinner.RSVPs[0].AttendeeName" type="text" value="kp" />
    <input id="Dinner_RSVPs[1]_RsvpID" name="Dinner.RSVPs[1].RsvpID" type="hidden" value="37" />
        <input id="Dinner_RSVPs[1]_DinnerID" name="Dinner.RSVPs[1].DinnerID" type="hidden" value="63" />
        <input id="Dinner_RSVPs[1]_AttendeeName" name="Dinner.RSVPs[1].AttendeeName" type="text" value="jim" />

    </p>   

我没有修改过DinnersControler的Post Edit Action方法。父母的晚餐照常更新,但它似乎是UpdateModel(晚餐);没有看到/更新子RSVP记录。

我在渲染子记录时尝试了一些变体,以便模型绑定器能够看到该集合,但没有运气。

通过调用UpdateModel(Parent)一次更新父/子记录;可以使用当前的模型粘合剂吗?

3 个答案:

答案 0 :(得分:4)

我自己无法做到这一点。

我知道您可以自动更新单个子元素,即Dinner.RSV。我从未见过更新子枚举的能力,这需要绑定才能知道哪个属性是ID并查找它(即Dinner.RSVP.Where(r =&gt; r.RSVP_ID == input_id)和然后更新那个)。我不太了解自定义绑定做类似的事情。

但是,我所做的是做一个循环并指定rsvp和int作为前缀:

所以你这样做:

UpdateModel("Dinner", Dinner);

更新父级,然后:

int i = 0;

foreach (var r in Dinner.RSVPs) {
  UpdateModel(r, "Dinner.RSVPs[" + i++ + "]");
}

不太干净,但对我来说效果很好。但是,构建验证可能需要更多的努力(您希望同时验证所有内容,并确保不会在第一个RSVP上跳回到错误的视图)。

编辑:修复了反映OP解决方案的代码,包括参数顺序中的错误。话虽如此,我使用RSVP.ID属性比运行整数更舒服。只要您知道Dinner.RSVP在POST上与GET相同(我在我的代码中对此有信心),那么使用RSVP.ID将起作用。如果RSVP与RSVP不同,那么只有那两个存在的RSVP才会更新。但是,使用sequential int可能会导致更新错误的对象。

希望有所帮助, 詹姆斯

答案 1 :(得分:0)

好的,所以没有人回答。我不知道nerddinner应用程序,但对您的问题感兴趣。希望看到一些答案,但是,还没有。不是100%肯定,因为对ndinner不熟悉,但它是否与this post有关,只有在明确传递属性时才提到绑定/更新?

答案 2 :(得分:0)

您的问题是通过调用UpdateModel(Parent)来一次更新父/子记录;可以使用当前的模型粘合剂吗?

是的,这是可能的。但是,如果您使用Linq-to-Sql并且您的子对象通过EntitySet<T>而不是像IList<T>那样公开,则可能(没有一些小的解决方法)。我相信这将是(已经?)在ASP.NET 4.0的下一版MVC中解决的问题。但就目前而言,MVC默认模型绑定器似乎并不了解如何使用EntitySet。

请看这个other answer我前段时间写过一个相关的问题,详细介绍了我在某些简单的情况下如何处理(解决)这种情况。在这样做的过程中,我不得不停止担心这个解决方案从DDD / OOP的角度来看是多么“理想”,作为简单地让MVC和LTS以最小的努力很好地协同工作的权衡。

注意,我会承认James S的解决方案可能更“纯粹”,但是为了在你所要求的“一次性”中做到这一点,你需要等待ASP.NET 4.0,或者使用解决方法类似于我在其他帖子中找到的内容。

祝你好运!