2012-05-29 1 views
5

Ich habe andere Fragen und Antworten auf dieser Seite durchgesehen, kann aber nicht die Antwort finden, die ich brauche.Wie wird ein Modell, das ein IEnumerable-Modell (komplex) enthält, von einer Ansicht C# MVC3 an einen Controller übergeben?

Ich habe eine StudentRecord Einheit:

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

Wie Sie es enthält eine einzelne StudentAddress Einheit und auch ein IEnumerable von StudentAddress sehen:

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

Ich bin vorbei ein Student Rekord Blick , enthalten in einem Viewmodel:

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

Dann zeigt es in einer Form, so dass ich t kann bearbeitet werden, und das Senden des Formulars übergibt den StudentRecord zurück an den Controller. Alles funktioniert gut, außer die Adressen innerhalb des StudentRecord sind null. Die einzelne StudentAddress in der StudentRecord ist für, wenn eine neue Adresse hinzugefügt wird, und das funktioniert auch.

Kann ich die Adressen bearbeiten und an den Controller zurücksenden, oder muss ich sie in einem separaten Formular auf einer separaten Seite speichern? Ich kann das tun, würde aber lieber alles in einem haben.

Mein Problem kann sein, dass es nicht möglich ist, oder es kann die Art sein, wie ich die Adressen in das Formular einfüge. Ein Student kann mehr als eine Adresse haben.

Hier ist die Form: (ich habe für Klarheit einige HTML-Layout gezupft Die ‚eine andere Adresse hinzufügen‘ tickbox zeigt den Adressabschnitt Neuer Student mit 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*@ 

Antwort

8

Das Problem, dass die name ist Attribute der Texteingabesteuerelemente enthalten keine korrekten Werte. Ich lade Sie ein, die following blog post zu lesen, um die Konvention besser zu verstehen, die vom Standardmodellbinder verwendet wird, um an Sammlungen und Wörterbücher zu binden.

Dann würde ich empfehlen Sie Editor Vorlagen anstatt foreach-Schleifen in Ihren Ansichten zu schreiben:

@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;"/> 
} 

und dann eine benutzerdefinierten Editor-Vorlage definieren, die für jedes Element der Sammlung Adressen (~/Views/Shared/EditorTemplates/StudentAddress.cshtml) automatisch gerendert werden :

@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) 

Aber das alles ist statisch. Wenn Sie in der Lage sein möchten, Adressen dynamisch hinzuzufügen und zu entfernen, lade ich Sie ein, die following blog post von Steven Sanderson zu lesen, in der er veranschaulicht, wie ein benutzerdefinierter HTML-Helper verwendet werden könnte, um Eigennamen für die Eingabefelder (Html.BeginCollectionItem) zu generieren und AJAX zu verwenden neue Zeilen.

+0

Vielen Dank für Ihre schnelle Antwort. Ich werde dies versuchen und einen Blick auf Ihre vorgeschlagene Lektüre werfen. Ich werde meine Ergebnisse hier veröffentlichen. Danke vielmals. – tekiegirl

+0

Danke, das hat perfekt funktioniert. Ich werde die Adressen dynamisch hinzufügen. – tekiegirl