2013-03-20 7 views
5

Übersicht: Ich versuche, ein Ansichtsmodell zu verwenden, das eine Eigenschaft hat, dass die Modellklasse, die ich versuche zu bearbeiten . Ich habe gesehen, wie das Bearbeitungsformular mit den MVC-Scaffolding-Bearbeitungsformularen funktioniert, wenn ich ein Modell direkt bearbeite. Ich versuche jedoch, ein ViewModel zu verwenden, das das bearbeitete Modell enthält. Alles funktioniert außer dem Speichern eines Felds, das in einer DropDownList angezeigt wird.MVC 3: Dropdownlist auf einem Formular bearbeitet für ein Objekt, das eine Eigenschaft einer Ansichtsmodell ist

Erläuterung: Ich habe versucht, die Gerüstfunktionen von MVC 3 zu verwenden, um ein Bearbeitungsformular für ein Modell zu erstellen. Im MVC Music Store-Lernprogramm wird dies für die Bearbeiten-Seite eines Album, in StoreManagerController getan. Innerhalb dieser Seite haben sie zwei Dropdown-Menüs für Genre und Künstler. Jeder sieht in der Ansicht ähnlich der: -

<div class="editor-label"> 
    @Html.LabelFor(model => model.GenreId, "Genre") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("GenreId", String.Empty) 
    @Html.ValidationMessageFor(model => model.GenreId) 
</div> 

Soweit ich das beurteilen kann, haben diese ihre Möglichkeiten in der Steuerung ausgefüllte die ViewBag verwenden.

ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); 
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); 

mit dem Modell arbeiten direkt

In meinem Code konnte ich das gleiche mit einem Objekt tun, die auf die DB über Entity Framework gespeichert ist wird.

Modell

public class Season 
{ 
    public int SeasonId { get; set; } 
    public int ClubId { get; set; } 
    public Club Club { get; set; } 
} 

-Code in Controller-

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", season.ClubId); 

Ansicht

<div class="editor-label"> 
    @Html.LabelFor(model => model.ClubId, "Club") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("ClubId", String.Empty) 
    @Html.ValidationMessageFor(model => model.ClubId) 
</div> 

Dies funktioniert gut.

Arbeiten mit der Ansicht Modell

aber jetzt habe ich erkannt, dass die Seite mehr Text als angezeigt muss, was im Modell verfügbar ist, ich bin Bearbeitung. Ich hatte gehofft, ein spezielles View Model zu erstellen, mit dem bearbeiteten Modell (Saison) und dem zusätzlichen Text, den ich anzeigen möchte.

Ansichtsmodell

public class EditSeasonViewModel 
{ 
    public string PlayerName {get; set;} 
    public string SummaryText {get; set;} 
    public int PlayerId {get; set;} 
    public Season season {get; set;} 
} 

ich dies tat, änderte sich die Controller die HttpGet und Httppost Methoden die neue Ansichtsmodell verwenden zu haben, änderte sich die Ansicht des neuen Ansichtsmodell zu übernehmen, und änderte die alle ‚EditorFor‘ Methoden in der Ansicht, um model.season.MyProperty zu verwenden.

-Code in Controller-

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", seasonVM.season.ClubId); 

-Code in Ansicht

<div class="editor-label"> 
    @Html.LabelFor(model => model.season.ClubId, "Club") 
</div> 
<div class="editor-field"> 
    @Html.DropDownList("ClubId", String.Empty) 
    @Html.ValidationMessageFor(model => model.season.ClubId) 
</div> 

Wenn die Methode Httppost Debuggen, alle Werte für die Saison richtig bestehen, mit Ausnahme des ClubId Wert, der von der DropDropList kommen sollte .

Ich habe die DropDownList in der Ansicht überhaupt nicht geändert, als wir das Model direkt benutzt haben.

Frage: Meine Frage ist, was muss ich die ClubId zu erhalten ändern richtig gespeichert werden, wenn diese neue EditSeasonViewModel mit?

Wie passt auch die ViewBag.ClubId in der HttpGet -Methode im Controller auf die DropDownList in der Ansicht, und dann hat es seinen Wert zurück an die HttpPost-Methode übergeben?

Antwort

9

Es ist Ihre DropDownList Erklärung, die falsch ist. Versuchen Sie stattdessen:

@Html.DropDownListFor(m => m.season.ClubId, ViewBag.ClubId) 

Aber wirklich, sollten Sie diese Auswahlliste im Modell setzen:

public SelectList Clubs { get; set; } 

Dann füllen Sie es in Ihrem Controller:

Model.Clubs = new SelectList(clubs, "ClubId", "Name", season.ClubId); 

Dann können Sie tun:

@Html.DropDownListFor(m => m.season.ClubId, Model.Clubs) 
+2

+1 für die Verwendung. Die Mehrheit der Dropdown-Listen-Fragen in [tag: asp.net-mvc] sind ein Ergebnis der Verwirrung in ViewBag, schwach typisierten Helfern und Modellbindungs-Problemen. –

+0

@SeanHolmesby Danke für die Bearbeitung :) – mattytommo

+0

@mattytommo - Ausgezeichnet. Das hat funktioniert. Ich bin vorgegangen und habe Ihren stark typisierten Helfer benutzt, der, wie Forty-Two sagt, ein besserer Weg ist, mit Drop-Down-Listen umzugehen. Ich denke ich verstehe jetzt den ganzen Prozess. –

3

Verwenden Sie keine dynamischen Objekte wie ViewBag/ViewData, um Daten von Aktionsmethoden in Ansichten zu übertragen. Wechseln Sie zum stark typisierten Ansatz.

Aktualisieren Sie Ihr Viewmodel, um 2 weitere Eigenschaften zu haben. eine, um eine Sammlung von verfügbaren Clubs zu halten, und eine, um den ausgewählten Club zu halten.

public class EditSeasonViewModel 
{ 
    public List<SelectListItem> Clubs { set;get;} 
    public int SelectedClub { set;get;} 

    public string PlayerName {get; set;} 
    public string SummaryText {get; set;} 
    public int PlayerId {get; set;} 
    public Season season {get; set;} 

    public EditSeasonViewModel() 
    { 
     Clubs=new List<SelectListItem>(); 
    } 
} 

Jetzt in Ihrer GET Aktion, erhalten die Clubs und an den Clubs Property laden.

public ActionResult create(int id) 
{ 
    var vm=new EditSeasonViewModel(); 
    vm.Clubs=GetListOfSelectListItemFromClubsFromSomeWhere(); 
    return View(vm); 
} 

GetListOfSelectListItemFromClubsFromSomeWhere unter der Annahme, ist eine Methode, die für Ihre Clubs

public List<SelectListItem> GetListOfSelectListItemFromClubsFromSomeWhere() 
{ 
    // to do : return List<SelectListItem> with Value and Text(ClubId Id & Name) 
} 

und Ihrer Ansicht nach eine Liste von SelectListItem zurückgibt, verwenden Sie die Html.DropDownListFor Hilfsmethode

@model EditSeasonViewModel 
@using(Html.Beginform()) 
{ 

    @Html.DropdownlistFor(x=>x.SelectedClub, 
          new SelectList(Model.Clubs,"Value","Text"),"select") 
    <input type="submit" /> 
} 

Wenn diese Form zu sein, ist gepostet, erhalten Sie die ID des ausgewählten Clubs in der SelectedClub Eigenschaft Ihres geposteten Modells.

0

Bitte achten Sie darauf, dass in Ihrem bearbeiten/creat Regler wird die Eigenschaft richtig binded: die stark typisierte Helfer

public async Task<ActionResult> Edit([Bind(Include = "SeasonId,ClubId, otherproperties"]){ 
// code ... 
} 
Verwandte Themen