簡體   English   中英

如何將包含IEnumerable模型(復雜)的模型從視圖C#MVC3傳遞到控制器中?

[英]How to pass a model containing an IEnumerable model (complex) into a controller from a view 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實體以及一個IEnumerable的StudentAddress:

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;        
    }

然后在表單中顯示它以便可以編輯,並提交表單將StudentRecord傳遞回控制器。 除了StudentRecord中的地址為空之外,一切正常。 StudentRecord中的單個StudentAddress用於添加新地址,並且也可以正常工作。

是否可以編輯地址並將其發送回控制器,或者我是否需要在單獨的頁面上以單獨的形式將它們放在一起? 我可以做到這一點,但我更願意把它全部合二為一。

我的問題可能是它不可能,或者可能是我將地址放入表單的方式。 學生可能有多個地址。

下面是表格:(為了清楚起見,我刪除了一些html布局。'添加另一個地址'復選框顯示帶有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*@

問題是文本輸入控件的name屬性不包含正確的值。 我邀請您閱讀以下博客文章,以更好地理解默認模型綁定器用於綁定到集合和詞典的約定。

然后我建議您使用編輯器模板,而不是在視圖中編寫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;"/>
}

然后定義一個自定義編輯器模板,該模板將自動為Addresses集合的每個元素呈現( ~/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的以下博客文章 ,其中說明了如何使用自定義HTML幫助程序為輸入字段生成專有名稱( Html.BeginCollectionItem )和使用AJAX添加新行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM