2012-05-29 34 views
5

我已浏览了本网站上的其他问题和答案,但无法找到我需要的答案。如何将包含IEnumerable模型(复杂)的模型从视图传递到控制器C#MVC3?

我有一个StudentRecord实体:

public class StudentRecord : Persistent { 
     public virtual string LastName { get; set; } 
     public virtual string FirstName { get; set; } 
     public virtual DateTime Dob { get; set; } 
     public virtual int StudentRef { get; set; } 
     public virtual IEnumerable<StudentAddress> Addresses { get; set; } 
     public virtual StudentAddress Address { get; set; } 
     public virtual string Notes { get; set; } 
    } 

正如你可以看到它包含一个单一的StudentAddress实体,也StudentAddress的IEnumerable:

public class StudentAddress: Persistent { 
     public virtual int StudentRef { get; set; } 
     public virtual string Addressee { get; set; } 
     public virtual string Property { get; set; } 
     public virtual string District { get; set; } 
     public virtual string PostalTown { get; set; } 
     public virtual string County { get; set; } 
     public virtual string Postcode { get; set; } 
    } 

我传递一个学生记录到一个视图,包含在一个视图模型中:

public class UserViewModel { 
     public StudentRecord Student;  
     public ICurrentUserService CurrentUserService; 
     public ParentUser ParentUser;   
    } 

然后显示它在一个窗体中,所以我t可以被编辑,并且提交表单将StudentRecord传递回控制器。除了StudentRecord中的地址都为空外,所有工作都正常。 StudentRecord中的单个StudentAddress用于添加新地址,并且工作正常。

是否可以编辑地址并将其发送回控制器,还是需要在单独的页面上以单独的形式提供地址?我可以做到这一点,但宁愿把它放在一个整体。

我的问题可能是它是不可能的,或者它可能是我把地址放入窗体的方式。学生可能有多个地址。

下面的形式:(我已经剥离出来为清楚起见一些HTML布局“添加另一个地址” tickbox显示与jQuery新生地址段。)

@using (Html.BeginForm()) { 
    Personal Details 
    Full Name: @Html.TextBoxFor(x => x.Student.FirstName) @Html.TextBoxFor(x => x.Student.LastName) 
    DOB: @Html.TextBoxFor(x => x.Student.Dob) 

    @if (Model.Student.Addresses.Any()) { 
     // Only print addresses if they exist 
      int count = 1; 
      int element = 0; 
       @if (Model.Student.Addresses.Count() > 1) { 
        foreach (var address in Model.Student.Addresses) { 
         Student Address @count 
         Addressee @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).Addressee) 
         Property @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).Property) 
         District @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).District) 
         Postal Town @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).PostalTown) 
         County @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).County) 
         Postcode @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(element).Postcode) 
         count++; 
         element++; 
        } //end foreach 
       } else { 
        Student Address 
        Addressee @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).Addressee) 
        Property @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).Property) 
        District @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).District) 
        Postal Town @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).PostalTown) 
        County @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).County) 
        Postcode @Html.TextBoxFor(x => x.Student.Addresses.ElementAt(0).Postcode) 
       } @*end if (Model.Student.Addresses.Count() > 1)*@ 

       Add another address @Html.CheckBox("Add another address", false, new {@id = "newBox"}) 

       New Student Address 
       Addressee @Html.TextBoxFor(x => x.Student.Address.Addressee) 
       Property @Html.TextBoxFor(x => x.Student.Address.Property) 
       District @Html.TextBoxFor(x => x.Student.Address.District) 
       Postal Town @Html.TextBoxFor(x => x.Student.Address.PostalTown) 
       County @Html.TextBoxFor(x => x.Student.Address.County) 
       Postcode @Html.TextBoxFor(x => x.Student.Address.Postcode) 
    } else { 
     No address for this student. 
    } @*end if (Model.Student.Addresses.Any())*@ 

    Notes: @Html.TextAreaFor(x => x.Student.Notes, new { @style = "width: 100%;"}) 

    <input type="submit" value="Send" class="btn btn-primary" style="clear: both;"/> 
} @*end of form*@ 

回答

8

的问题是,name文本输入控件的属性不包含正确的值。我邀请您阅读following blog post以更好地理解默认模型联编程序用于绑定到集合和词典的约定。

那我就推荐你使用编辑器的模板,而不是在你的看法写foreach循环:

@using (Html.BeginForm()) { 
    Personal Details 

    @Html.LabelFor(x => x.Student.FirstName, "Full Name:") 
    @Html.EditorFor(x => x.Student.FirstName) 
    @Html.EditorFor(x => x.Student.LastName) 

    @Html.LabelFor(x => x.Student.Dob, "DOB:") 
    @Html.TextBoxFor(x => x.Student.Dob) 

    @if (Model.Student.Addresses.Any()) { 
     @Html.EditorFor(x => x.Student.Addresses) 
    } else { 
     <text>No address for this student.</text> 
    } 

    @Html.LabelFor(x => x.Student.Notes, "Notes:") 
    @Html.TextAreaFor(x => x.Student.Notes, new { @style = "width: 100%;"}) 

    <input type="submit" value="Send" class="btn btn-primary" style="clear: both;"/> 
} 

,然后定义将被自动呈现的地址集合中的每个元素的自定义编辑器模板(~/Views/Shared/EditorTemplates/StudentAddress.cshtml) :

@model StudentAddress 
@Html.LabelFor(x => x.Addressee, "Addressee") 
@Html.EditorFor(x => x.Addressee) 

@Html.LabelFor(x => x.Property, "Property") 
@Html.EditorFor(x => x.Property) 

@Html.LabelFor(x => x.District, "District") 
@Html.EditorFor(x => x.District) 

@Html.LabelFor(x => x.PostalTown, "Postal Town") 
@Html.EditorFor(x => x.PostalTown) 

@Html.LabelFor(x => x.County, "County") 
@Html.EditorFor(x => x.County) 

@Html.LabelFor(x => x.Postcode, "Postcode") 
@Html.EditorFor(x => x.Postcode) 

但是,这一切都是静态的。如果您希望能够动态添加和删除地址,我邀请您阅读Steven Sanderson的following blog post,其中他演示了如何使用自定义HTML助手为输入字段生成专有名称(Html.BeginCollectionItem)并使用AJAX添加新的行。

+0

感谢您的快速回复。我会试一试,看看你的建议阅读内容。我将在此发布我的结果。非常感谢。 – tekiegirl

+0

谢谢,这工作完美。我会考虑动态地添加地址。 – tekiegirl

相关问题