2012-05-29 11 views
5

Przejrzałem inne pytania i odpowiedzi na tej stronie, ale nie mogę znaleźć odpowiedzi, której potrzebuję.Jak przekazać model zawierający model IEnumerable (complex) do kontrolera z widoku C# MVC3?

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

Jak widać to zawiera jeden podmiot StudentAddress a także IEnumerable z 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; } 
    } 

ja przechodząc rekord studentów do widzenia , zawarte w modelu podglądu:

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

Następnie wyświetlanie go w formie, tak aby t można edytować, a przesłanie formularza przekazuje StudentRecord z powrotem do kontrolera. Wszystko działa dobrze, z wyjątkiem adresów w StudentRecord są zerowe. Pojedynczy adres StudentAddress w StudentRecord służy do dodawania nowego adresu i to też działa dobrze.

Czy można edytować i przesłać adresy z powrotem do kontrolera, czy też muszę mieć je w osobnym formularzu na oddzielnej stronie? Mogę to zrobić, ale wolałbym mieć wszystko w jednym.

Moim problemem może być to, że nie jest to możliwe lub może to być sposób w jaki umieszczam adresy w formularzu. Student może mieć więcej niż jeden adres.

Oto postać: (Mam odpędza się jakiś układ HTML dla jasności „Dodaj kolejny adres” tickbox przedstawia przekrój Adres New Student z 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*@ 

Odpowiedz

8

Problemem jest to, że name atrybuty elementów sterujących wprowadzaniem tekstu nie zawierają poprawnych wartości. Zapraszam do lektury following blog post, aby lepiej zrozumieć konwencję używaną przez domyślny spinacz modelu, aby powiązać kolekcje i słowniki.

to polecam Ci pomocą szablonów edytora zamiast pisać pętla foreach w widokach:

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

a następnie zdefiniować szablon niestandardowy edytor, który będzie automatycznie świadczonych dla każdego elementu zbioru adresów (~/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) 

Ale to wszystko jest statyczne. Jeśli chcesz dynamicznie dodawać i usuwać adresy, zapraszam do przeczytania artykułu following blog post ze strony Stevena Sandersona, w którym ilustruje, w jaki sposób można użyć niestandardowego pomocnika HTML do wygenerowania odpowiednich nazw dla pól wejściowych (Html.BeginCollectionItem) i użyć AJAX do dodania nowe wiersze.

+0

Dziękuję za szybką odpowiedź. Spróbuję tego i popatrzę na sugerowaną lekturę. Opublikuję tutaj moje wyniki. Wielkie dzięki. – tekiegirl

+0

Dziękuję, to działało idealnie. Przyjrzę się również dynamicznemu dodawaniu adresów. – tekiegirl

Powiązane problemy