Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V Průzkumník řešení klikněte pravým tlačítkem myši na složku Kontrolery a pak vyberte Přidat kontroler. Pojmenujte řadič StoreManagerController. Nastavte možnosti dialogového okna Přidat kontroler , jak je znázorněno na obrázku níže.

Upravte zobrazení StoreManager\Index.cshtml a odeberte AlbumArtUrl. Odebráním AlbumArtUrl bude prezentace čitelnější. Dokončený kód je uvedený níže.
@model IEnumerable<MvcMusicStore.Models.Album>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Genre
</th>
<th>
Artist
</th>
<th>
Title
</th>
<th>
Price
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Artist.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
@Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
</td>
</tr>
}
</table>
Otevřete soubor Controllers\StoreManagerController.cs a vyhledejte metoduIndex. Přidejte klauzuli OrderBy , aby alba byla seřazena podle ceny. Kompletní kód je uvedený níže.
public ViewResult Index()
{
var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist)
.OrderBy(a => a.Price);
return View(albums.ToList());
}
Řazení podle ceny usnadní testování změn v databázi. Při testování metod úprav a vytváření můžete použít nízkou cenu, aby se uložená data zobrazovala jako první.
Otevřete soubor StoreManager\Edit.cshtml. Přidejte následující řádek těsně za značku legendy.
@Html.HiddenFor(model => model.AlbumId)
Následující kód ukazuje kontext této změny:
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Album</legend>
@Html.HiddenFor(model => model.AlbumId)
<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>
<!-- Items removed for brevity. -->
}
Je AlbumId nutné provést změny v záznamu alba.
Stiskněte klávesy CTRL+F5 a spusťte aplikaci. Vyberte odkaz Správce a pak výběrem odkazu Vytvořit nový vytvořte nové album. Ověřte, že byly uloženy informace o albu. Upravte album a ověřte, že provedené změny jsou trvalé.
Schéma alba
StoreManager Kontroler vytvořený mechanismem generování uživatelského rozhraní MVC umožňuje CRUD (Create, Read, Update, Delete) přístup k albům v databázi úložiště hudby. Schéma informací o albu je znázorněno níže:

Tabulka Albums neukládá žánr a popis alba, ukládá cizí klíč do Genres tabulky. Tabulka Genres obsahuje název a popis žánru. Albums Stejně tak tabulka neobsahuje název umělce alba, ale cizí klíč tabulkyArtists. Tabulka Artists obsahuje jméno autora. Pokud prozkoumáte data v Albums tabulce, můžete vidět, že každý řádek obsahuje cizí klíč tabulky Genres a cizí klíč tabulky Artists . Na následujícím obrázku jsou některá data tabulky z Albums tabulky.

Značka Pro výběr HTML
Element HTML <select> (vytvořený pomocným rutinou HTML DropDownList ) slouží k zobrazení kompletního seznamu hodnot (například seznam žánrů). Při úpravách formulářů, pokud je aktuální hodnota známá, může seznam výběru zobrazit aktuální hodnotu. Viděli jsme to dříve, když jsme nastavili vybranou hodnotu na Comedy. Seznam výběrů je ideální pro zobrazení dat kategorie nebo cizího klíče. Prvek <select> cizího klíče Žánr zobrazuje seznam možných názvů žánrů, ale když uložíte formulář Žánr vlastnost se aktualizuje hodnotou cizího klíče Žánr, nikoli zobrazovaný název žánru. Na obrázku níže je žánr vybraný Disko a umělec je Donna Summer.

Prozkoumání kódu vygenerovaného uživatelského rozhraní MVC ASP.NET
Otevřete soubor Controllers\StoreManagerController.cs a vyhledejte metoduHTTP GET Create.
public ActionResult Create()
{
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name");
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name");
return View();
}
Metoda Create přidá dva SelectList objekty do ViewBag, jeden obsahovat informace o žánru, a jeden, který bude obsahovat informace interpreta. Přetížení konstruktoru SelectList použité výše přebírá tři argumenty:
public SelectList(
IEnumerable items,
string dataValueField,
string dataTextField
)
- items: IEnumerable obsahující položky v seznamu. V předchozím příkladu seznam žánrů vrácených
db.Genres. - dataValueField: Název vlastnosti v seznamu IEnumerable , který obsahuje hodnotu klíče. V příkladu výše
GenreIdaArtistId. - dataTextField: Název vlastnosti v seznamu IEnumerable , který obsahuje informace k zobrazení. V tabulce umělců i žánrů se
namepole používá.
Otevřete soubor Views\StoreManager\Create.cshtml a prozkoumejte Html.DropDownList pomocné značky pro pole žánru.
@model MvcMusicStore.Models.Album
@* Markup removed for clarity.*@
@Html.DropDownList("GenreId", String.Empty)
První řádek ukazuje, že zobrazení pro vytvoření používá Album model. Create Ve výše uvedené metodě nebyl předán žádný model, takže zobrazení získá model s hodnotou nullAlbum. V tuto chvíli vytváříme nové album, takže pro něj nemáme žádná Album data.
Přetížení Html.DropDownList zobrazené výše přebírá název pole, které se má svázat s modelem. Tento název také používá k vyhledání objektu ViewBag obsahující objekt SelectList . Pomocí tohoto přetížení je nutné pojmenovat ViewBag SelectList objekt GenreId. Druhý parametr (String.Empty) je text, který se má zobrazit, když není vybrána žádná položka. To je přesně to, co chceme při vytváření nového alba. Pokud jste odebrali druhý parametr a použili následující kód:
@Html.DropDownList("GenreId")
Výběrový seznam by ve výchozím nastavení byl první prvek nebo Rock v naší ukázce.

HTTP POST Create Zkoumání metody.
//
// POST: /StoreManager/Create
[HttpPost]
public ActionResult Create(Album album)
{
if (ModelState.IsValid)
{
db.Albums.Add(album);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name",
album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name",
album.ArtistId);
return View(album);
}
Toto přetížení Create metody přebírá album objekt vytvořený systémem vazby modelu ASP.NET MVC z publikovaných hodnot formuláře. Když odešlete nové album, pokud je stav modelu platný a nedojde k žádným chybám databáze, přidá se nové album do databáze. Následující obrázek znázorňuje vytvoření nového alba.

Nástroj fiddler můžete použít k prozkoumání odeslaných hodnot formuláře, které ASP.NET vazby modelu MVC používá k vytvoření objektu alba.
.
Refaktoring vytvoření selectlistu ViewBag
Metody Edit i HTTP POST Create metoda mají identický kód pro nastavení SelectList v ViewBag. V duchu DRY budeme refaktorovat tento kód. Tento refaktorovaný kód použijeme později.
Vytvořte novou metodu pro přidání žánru a interpreta SelectList do ViewBag.
private void SetGenreArtistViewBag(int? GenreID = null, int? ArtistID = null) {
if (GenreID == null)
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name");
else
ViewBag.GenreId = new SelectList(db.Genres.ToArray(), "GenreId", "Name", GenreID);
if (ArtistID == null)
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name");
else
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", ArtistID);
}
Nahraďte dva řádky, které nastaví ViewBag v jednotlivých metodách Create Edit , voláním SetGenreArtistViewBag metody. Dokončený kód je uvedený níže.
//
// GET: /StoreManager/Create
public ActionResult Create() {
SetGenreArtistViewBag();
return View();
}
//
// POST: /StoreManager/Create
[HttpPost]
public ActionResult Create(Album album) {
if (ModelState.IsValid) {
db.Albums.Add(album);
db.SaveChanges();
return RedirectToAction("Index");
}
SetGenreArtistViewBag(album.GenreId, album.ArtistId);
return View(album);
}
//
// GET: /StoreManager/Edit/5
public ActionResult Edit(int id) {
Album album = db.Albums.Find(id);
SetGenreArtistViewBag(album.GenreId, album.ArtistId);
return View(album);
}
//
// POST: /StoreManager/Edit/5
[HttpPost]
public ActionResult Edit(Album album) {
if (ModelState.IsValid) {
db.Entry(album).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
SetGenreArtistViewBag(album.GenreId, album.ArtistId);
return View(album);
}
Vytvořte nové album a upravte album, abyste ověřili, že změny fungují.
Explicitní předání seznamu SelectList do rozevíracího seznamu
Při vytváření a úpravách zobrazení vytvořených generováním ASP.NET MVC se používá následující přetížení DropDownList :
public static MvcHtmlString DropDownList(
this HtmlHelper htmlHelper,
string name, // The name of the ViewModel property to bind.
string optionLabel // The string added to the top of the list
// typically String.Empty or "Select a Genre"
)
Kód DropDownList pro zobrazení pro vytvoření je uvedený níže.
@Html.DropDownList("GenreId", String.Empty)
ViewBag Protože vlastnost pro název SelectList GenreId, DropDownList pomocník bude používatGenreId SelectList v ViewBag. V následujícím dropDownList přetížení je SelectList explicitně předán.
public static MvcHtmlString DropDownList(
this HtmlHelper htmlHelper,
string name, // The name of the ViewModel property to bind.
IEnumerable selectList // The SelectList
)
Otevřete soubor Views\StoreManager\Edit.cshtml a změňte volání DropDownList explicitně předat SelectList pomocí přetížení výše. Udělejte to pro kategorii Žánr. Dokončený kód je uvedený níže:
@Html.DropDownList("GenreId", ViewBag.GenreId as SelectList)
Spusťte aplikaci a klikněte na odkaz Správce , přejděte do alba Jazz a vyberte odkaz Upravit .

Místo zobrazení Jazzu jako aktuálně vybraného žánru se zobrazí Rock. Pokud řetězcový argument (vlastnost vytvořit vazbu) a selectList objekt mají stejný název, vybraná hodnota se nepoužije. Pokud není k dispozici žádná vybraná hodnota, prohlížeče ve výchozím nastavení první prvek v SelectList(což je Rock v příkladu výše). Toto je známé omezení pomocné rutiny DropDownList .
Otevřete soubor Controllers\StoreManagerController.cs a změňte názvy objektů SelectList na Genres a Artists. Dokončený kód je uvedený níže:
private void SetGenreArtistViewBag(int? GenreID = null, int? ArtistID = null) {
if (GenreID == null)
ViewBag.Genres = new SelectList(db.Genres, "GenreId", "Name");
else
ViewBag.Genres = new SelectList(db.Genres.ToArray(), "GenreId", "Name", GenreID);
if (ArtistID == null)
ViewBag.Artists = new SelectList(db.Artists, "ArtistId", "Name");
else
ViewBag.Artists = new SelectList(db.Artists, "ArtistId", "Name", ArtistID);
}
Názvy Žánry a umělci jsou lepšími názvy kategorií, protože obsahují více než jen ID každé kategorie. Refaktoring, který jsme udělali dříve, se vyplatil. Místo změny ViewBagu ve čtyřech metodách byly naše změny izolované pro metoduSetGenreArtistViewBag.
Změňte volání DropDownList v zobrazení pro vytvoření a úpravu tak, aby používaly nové názvy SelectList. Nový kód pro zobrazení pro úpravy je zobrazený níže:
<div class="editor-label">
@Html.LabelFor(model => model.GenreId, "Genre")
</div>
<div class="editor-field">
@Html.DropDownList("GenreId", ViewBag.Genres as SelectList)
@Html.ValidationMessageFor(model => model.GenreId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArtistId, "Artist")
</div>
<div class="editor-field">
@Html.DropDownList("ArtistId", ViewBag.Artists as SelectList)
@Html.ValidationMessageFor(model => model.ArtistId)
</div>
Zobrazení Vytvořit vyžaduje prázdný řetězec, aby se zabránilo zobrazení první položky v seznamu SelectList.
<div class="editor-label">
@Html.LabelFor(model => model.GenreId, "Genre" )
</div>
<div class="editor-field">
@Html.DropDownList("GenreId", ViewBag.Genres as SelectList, String.Empty)
@Html.ValidationMessageFor(model => model.GenreId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArtistId, "Artist")
</div>
<div class="editor-field">
@Html.DropDownList("ArtistId", ViewBag.Artists as SelectList, String.Empty)
@Html.ValidationMessageFor(model => model.ArtistId)
</div>
Vytvořte nové album a upravte album, abyste ověřili, že změny fungují. Otestujte kód úprav tak, že vyberete album s jiným žánrem než Rock.
Použití modelu zobrazení s pomocným nástrojem DropDownList
Vytvořte novou třídu ve složce ViewModels s názvem AlbumSelectListViewModel. Nahraďte kód ve AlbumSelectListViewModel třídě následujícím kódem:
using MvcMusicStore.Models;
using System.Web.Mvc;
using System.Collections;
namespace MvcMusicStore.ViewModels {
public class AlbumSelectListViewModel {
public Album Album { get; private set; }
public SelectList Artists { get; private set; }
public SelectList Genres { get; private set; }
public AlbumSelectListViewModel(Album album,
IEnumerable artists,
IEnumerable genres) {
Album = album;
Artists = new SelectList(artists, "ArtistID", "Name", album.ArtistId);
Genres = new SelectList(genres, "GenreID", "Name", album.GenreId);
}
}
}
Konstruktor AlbumSelectListViewModel vezme album, seznam umělců a žánrů a vytvoří objekt obsahující album a SelectList žánry a umělce.
Sestavte projekt tak, aby AlbumSelectListViewModel byl k dispozici při vytváření zobrazení v dalším kroku.
Přidejte metodu EditVM do objektu StoreManagerController. Dokončený kód je uvedený níže.
//
// GET: /StoreManager/EditVM/5
public ActionResult EditVM(int id) {
Album album = db.Albums.Find(id);
if (album == null)
return HttpNotFound();
AlbumSelectListViewModel aslvm = new AlbumSelectListViewModel(album, db.Artists, db.Genres);
return View(aslvm);
}
Klikněte pravým tlačítkem myši , vyberte Přeložit a pak použijte MvcMusicStore.ViewModels;.AlbumSelectListViewModel

Alternativně můžete přidat následující příkaz using:
using MvcMusicStore.ViewModels;
Klikněte pravým tlačítkem myši EditVM a vyberte Přidat zobrazení. Použijte níže uvedené možnosti.

Vyberte Přidat a pak nahraďte obsah souboru Views\StoreManager\EditVM.cshtml následujícím kódem:
@model MvcMusicStore.ViewModels.AlbumSelectListViewModel
@{
ViewBag.Title = "EditVM";
}
<h2>Edit VM</h2>
@using (Html.BeginForm("Edit","StoreManager",FormMethod.Post)) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Album</legend>
@Html.HiddenFor(model => model.Album.AlbumId )
<div class="editor-label">
@Html.LabelFor(model => model.Album.GenreId, "Genre")
</div>
<div class="editor-field">
@Html.DropDownList("Album.GenreId", Model.Genres)
@Html.ValidationMessageFor(model => model.Album.GenreId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Album.ArtistId, "Artist")
</div>
<div class="editor-field">
@Html.DropDownList("Album.ArtistId", Model.Artists)
@Html.ValidationMessageFor(model => model.Album.ArtistId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Album.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Album.Title)
@Html.ValidationMessageFor(model => model.Album.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Album.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Album.Price)
@Html.ValidationMessageFor(model => model.Album.Price)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Album.AlbumArtUrl)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Album.AlbumArtUrl)
@Html.ValidationMessageFor(model => model.Album.AlbumArtUrl)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Kód EditVM je velmi podobný původnímu Edit kódu s následujícími výjimkami.
- Vlastnosti modelu v
Editzobrazení jsou ve formulářimodel.property(napříkladmodel.Title). Vlastnosti modelu vEditVmzobrazení jsou ve formulářimodel.Album.property(napříkladmodel.Album.Title). Je to proto, žeEditVMzobrazení se předává kontejneru pro objektAlbum, nikoli jakoAlbumvEditzobrazení. - Druhý parametr DropDownList pochází z modelu zobrazení, nikoli ViewBag.
- Pomocná rutina BeginForm v
EditVMzobrazení explicitně publikuje zpět doEditmetody akce. Odesláním zpět naEditakci nemusíme napsatHTTP POST EditVMakci a akci znovu použítHTTP POSTEdit.
Spusťte aplikaci a upravte album. Změňte adresu URL tak, aby používala EditVM. Změňte pole a stisknutím tlačítka Uložit ověřte, že kód funguje.

Jaký přístup byste měli použít?
Všechny tři zobrazené přístupy jsou přijatelné. Mnoho vývojářů dává přednost tomu, aby explicitně předalo SelectList DropDownList použití ViewBag. Díky tomuto přístupu získáte větší flexibilitu při používání vhodnějšího názvu kolekce. Jedním upozorněním je, že objekt nemůže pojmenovat ViewBag SelectList stejný název jako vlastnost modelu.
Někteří vývojáři dávají přednost přístupu ViewModel. Ostatní považují za nevýhodu více podrobných značek a vygenerovaný kód HTML modelu ViewModel.
V této části jsme se naučili tři přístupy k používání rozevíracího seznamu s daty kategorií. V další části si ukážeme, jak přidat novou kategorii.