为什么MVC不绑定我的嵌套集合?

时间:2010-10-01 21:39:17

标签: c# asp.net-mvc linq-to-sql asp.net-mvc-2 forms

如果我想通过表单编辑几个linqTOsql对象。

首先,有Stream类:

[Table]
public class Stream
{
    [HiddenInput(DisplayValue = false)]
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public long StreamID { get; set; }

    /*other properties removes for brevity*/

    // relationship (one stream to many Stream2FieldTypes) 
    // uses EntitySet<Stream2FieldTypes> and OtherKey for the FK in Stream2FieldTypes 
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes;
    [System.Data.Linq.Mapping.Association(Storage = "_Stream2FieldTypes", OtherKey = "StreamID")]
    public EntitySet<Stream2FieldTypes> Stream2FieldTypes
    {
        get { return this._Stream2FieldTypes; }
        set { this._Stream2FieldTypes.Assign(value); }
    }

}

然后是Stream2FieldTypes类:

[Table]
public class Stream2FieldTypes
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public long s2fID { get; set; }

    /*other properties removed for brevity*/

    [Column]
    public long StreamID { get; set; }     // FK




    // relationship (one Stream2FieldTypes to Streams) 
    private EntitySet<Stream> _Stream;
    [Association(Storage = "_Stream", ThisKey = "StreamID")]
    public EntitySet<Stream> Stream
    {
        get { return this._Stream; }
        set { this._Stream.Assign(value); }
    }
}

我使用linqTOsql存储库来获取这些对象并将它们发送到视图,如下所示:

    public ActionResult StreamEdit(long id)
    {
        Genesis.Domain.Entities.Stream stream = genesisRepository.Streams.FirstOrDefault(x => x.StreamID == id);

        return View(stream);
    }

一切都被发送到视图而没有问题......但是当提交视图上的表单时,Stream.Stream2FieldTypes由于某种原因而丢失。我通过此操作捕获表单提交:

    [HttpPost]
    public ActionResult StreamEdit( long id, Genesis.Domain.Entities.Stream form)
    {

            return View(form);
    }

视图没有Stream2FieldTypes集合。

视图正在编写Stream2FieldTypes,如下所示:

<% for (int i = 0; i < (Model.Stream2FieldTypes != null ? Model.Stream2FieldTypes.Count() : 0); i++) %>
<% { %>
    <div class="ListItem">
        Label: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].s2fLabel, new { style="width:100px" })%>
        Required: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].s2fIsRequired)%>
        Field Type ID": <%: Html.EditorFor(x => x.Stream2FieldTypes[i].FieldTypeID, new { style="width:20px;" })%>
        Stream ID: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].StreamID) %>
</div>
<% } %>

为什么mvc中的默认模型绑定器没有正确绑定嵌套集合?

1 个答案:

答案 0 :(得分:2)

我建议您使用POCO视图模型而不是那些杂乱的模型类。它们不适应视图并且难以使用。尝试绑定到像EntitySet<T>这样的LINQ特定集合并不是一个好主意。这是使用编辑器模板可能实际上工作,但即使这工作,请记住,它应该是一个临时解决方案,直到您引入正确的视图模型。

在主视图中用以下代码替换循环:

<%: Html.EditorFor(x => x.Stream2FieldTypes) %>

然后在~/Views/Home/EditorTemplates/Stream2FieldTypes.ascx中添加强类型的部分视图:

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<SomeNs.Stream2FieldTypes>" 
%>
<div class="ListItem">
    Label: 
    <%: Html.EditorFor(x => x.s2fLabel, new { style="width:100px" }) %>

    Required: 
    <%: Html.EditorFor(x => x.s2fIsRequired) %>

    Field Type ID: 
    <%: Html.EditorFor(x => x.FieldTypeID, new { style="width:20px;" })%>

    Stream ID: 
    <%: Html.EditorFor(x => x.StreamID) %>
</div>

通常这应该注意生成正确的输入名称,但为了避免人们把它作为一个好例子:我再次重复使用正确的视图模型。