Hledat
Poznámka
Aktualizovaná verze tohoto kurzu je k dispozici tady s nejnovější verzí sady Visual Studio. Nový kurz používá ASP.NET Core MVC, který oproti tomuto kurzu poskytuje mnoho vylepšení.
V tomto kurzu se naučíte ASP.NET Core MVC s kontrolery a zobrazeními. Razor Pages je novou alternativou v ASP.NET Core, což je stránkový programovací model, který usnadňuje a zlepšuje produktivitu vytváření webového uživatelského rozhraní. Doporučujeme vyzkoušet kurz Razor Pages před verzí MVC. Kurz k Razor Pages:
- Je jednodušší ho sledovat.
- Zahrnuje další funkce.
- Je upřednostňovaným přístupem pro vývoj nových aplikací.
Přidání metody hledání a zobrazení hledání
V této části přidáte do Index
metody akce funkci vyhledávání, která vám umožní vyhledávat filmy podle žánru nebo názvu.
Požadavky
Aby se snímky obrazovky této části odpovídaly, musíte spustit aplikaci (F5) a přidat do databáze následující filmy.
Nadpis | Datum vydání | Žánr | Cena |
---|---|---|---|
Ghostbusters | 6/8/1984 | Komedie | 6.99 |
Duchové II | 6/16/1989 | Komedie | 6.99 |
Planeta ope | 3/27/1986 | Akce | 5.99 |
Aktualizuje se indexový formulář
Začněte aktualizací Index
metody action na existující MoviesController
třídu. Tady je kód:
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
První řádek Index
metody vytvoří následující dotaz LINQ pro výběr filmů:
var movies = from m in db.Movies
select m;
Dotaz je definován v tomto okamžiku, ale dosud nebyl spuštěn pro databázi.
searchString
Pokud parametr obsahuje řetězec, dotaz movies se upraví tak, aby filtrovaly hodnotu hledaného řetězce pomocí následujícího kódu:
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
Výše s => s.Title
uvedený kód je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je například metoda Where použitá ve výše uvedeném kódu. Dotazy LINQ se nespouštějí, když jsou definované nebo když jsou upraveny voláním metody, jako Where
je nebo OrderBy
. Místo toho se provádění dotazu odloží, což znamená, že vyhodnocení výrazu se zpozdí, dokud se jeho realizované hodnota skutečně nepřečte nebo ToList
dokud se metoda nevolá. V ukázce se Search
dotaz spustí v zobrazení Index.cshtml . Další informace o odložené provádění dotazů najdete v tématu Provádění dotazů.
Poznámka
Metoda Contains se spouští v databázi, nikoli ve výše uvedeném kódu jazyka C#. V databázi obsahuje mapování na SQL LIKE, což nerozlišuje malá a velká písmena.
Teď můžete aktualizovat Index
zobrazení, které zobrazí formulář uživateli.
Spusťte aplikaci a přejděte na /Movies/Index. K adrese URL připojte řetězec dotazu, například ?searchString=ghost
. Zobrazí se filtrované filmy.
Pokud změníte podpis Index
metody tak, aby měl parametr s názvem id
, id
bude parametr odpovídat {id}
zástupné symbolu pro výchozí trasy nastavené v souboru App_Start\RouteConfig.cs .
{controller}/{action}/{id}
Původní Index
metoda vypadá takto:
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
Upravená Index
metoda by vypadala takto:
public ActionResult Index(string id)
{
string searchString = id;
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
Název hledání teď můžete předat jako data trasy (segment adresy URL) místo jako hodnotu řetězce dotazu.
Nemůžete ale očekávat, že uživatelé upraví adresu URL pokaždé, když budou chtít hledat film. Teď tedy přidáte uživatelské rozhraní, které jim pomůže filtrovat filmy. Pokud jste změnili signaturu Index
metody, abyste otestovali, jak předat parametr ID vázaného na trasu, změňte ho zpět tak, aby vaše Index
metoda přebírá řetězcový parametr s názvem searchString
:
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
Otevřete soubor Views\Movies\Index.cshtml a hned za @Html.ActionLink("Create New", "Create")
přidejte níže zvýrazněný kód formuláře:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString") <br />
<input type="submit" value="Filter" /></p>
}
</p>
Pomocná rutina Html.BeginForm
vytvoří počáteční <form>
značku. Pomocná rutina Html.BeginForm
způsobí, že se formulář publikuje sám, když uživatel odešle formulář kliknutím na tlačítko Filtr .
Visual Studio 2013 má skvělé vylepšení při zobrazování a úpravách zobrazit soubory. Když spustíte aplikaci s otevřeným souborem zobrazení, Visual Studio 2013 vyvolá správnou metodu akce kontroleru pro zobrazení.
V sadě Visual Studio otevřete zobrazení Index (jak je vidět na obrázku výše), klepnutím na Ctr F5 nebo F5 spusťte aplikaci a zkuste vyhledat film.
Metoda není HttpPost
přetížená Index
. Nepotřebujete ho, protože metoda nemění stav aplikace, ale jenom filtruje data.
Můžete přidat následující HttpPost Index
metodu. V takovém případě by se vyvolávací akce shodoval s metodou HttpPost Index
a HttpPost Index
metoda by se spustila, jak je znázorněno na obrázku níže.
[HttpPost]
public string Index(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]Index: " + searchString + "</h3>";
}
I když ale přidáte tuto HttpPost
verzi Index
metody, platí omezení způsobu implementace. Představte si, že chcete přidat do záložek konkrétní hledání nebo chcete přátelům poslat odkaz, na který můžou kliknout, aby se zobrazil stejný filtrovaný seznam filmů. Všimněte si, že adresa URL požadavku HTTP POST je stejná jako adresa URL požadavku GET (localhost:xxxxx/Movies/Index) – v samotné adrese URL nejsou žádné informace o hledání. V tuto chvíli se informace o hledaném řetězci odesílají na server jako hodnota pole formuláře. To znamená, že tyto vyhledávací informace nemůžete zachytit, abyste si je mohli uložit do záložek nebo poslat přátelům v adrese URL.
Řešením je použít přetížení BeginForm
, které určuje, že požadavek POST by měl přidat informace o hledání do adresy URL a že by měly být směrovány do HttpGet
verze Index
metody . Existující metodu bez BeginForm
parametrů nahraďte následujícím kódem:
@using (Html.BeginForm("Index","Movies",FormMethod.Get))
Když teď odešlete hledání, bude adresa URL obsahovat řetězec vyhledávacího dotazu. Hledání také přejde na metodu HttpGet Index
akce, i když máte metodu HttpPost Index
.
Přidání hledání podle žánru
Pokud jste přidali HttpPost
verzi Index
metody , odstraňte ji nyní.
V dalším kroku přidáte funkci, která uživatelům umožní hledat filmy podle žánru. Nahraďte metodu Index
následujícím kódem:
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
Tato verze Index
metody přebírá další parametr, a sice movieGenre
. Prvních několik řádků kódu vytvoří objekt pro List
uložení filmových žánrů z databáze.
Následující kód je dotaz LINQ, který z databáze načte všechny žánry.
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
Kód používá metodu AddRange
obecné List
kolekce k přidání všech různých žánrů do seznamu. (Bez modifikátoru Distinct
by se přidaly duplicitní žánry – například komedie by se v naší ukázce přidala dvakrát).) Kód pak uloží seznam žánrů v objektu ViewBag.MovieGenre
. Ukládání dat kategorií (jako jsou filmové žánry) jako objekt SelectList v objektu ViewBag
a pak přístup k datům kategorií v rozevíracím seznamu je typickým přístupem pro aplikace MVC.
Následující kód ukazuje, jak zkontrolovat movieGenre
parametr . Pokud není prázdný, kód dále omezí dotaz na filmy a omezí vybrané filmy na zadaný žánr.
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
Jak jsme uvedli dříve, dotaz se nespustí v databázi, dokud se nepřečte iterace seznamu filmů (k čemuž dojde v Zobrazení po Index
vrácení metody akce).
Přidání revizí do zobrazení indexu pro podporu vyhledávání podle žánru
Přidejte pomocné rutiny Html.DropDownList
do souboru Views\Movies\Index.cshtml těsně před pomocnou rutinu TextBox
. Dokončená revize je zobrazena níže:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="table">
V následujícím kódu:
@Html.DropDownList("movieGenre", "All")
Parametr "MovieGenre" poskytuje klíč, aby DropDownList
pomocník našel IEnumerable<SelectListItem>
v ViewBag
. Hodnota ViewBag
byla vyplněna v metodě akce:
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
Parametr All poskytuje popisek možnosti. Pokud tuto volbu zkontrolujete v prohlížeči, uvidíte, že její atribut value je prázdný. Vzhledem k tomu, že kontroler filtruje if
pouze řetězec není null
nebo není prázdný, odeslání prázdné hodnoty pro movieGenre
zobrazí všechny žánry.
Můžete také nastavit možnost, která se má ve výchozím nastavení vybrat. Pokud byste chtěli jako výchozí možnost "Comedy", změnili byste kód v kontroleru takto:
ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");
Spusťte aplikaci a přejděte na /Movies/Index. Zkuste hledat podle žánru, podle názvu filmu a podle obou kritérií.
V této části jste vytvořili metodu a zobrazení akce hledání, které uživatelům umožňuje hledat podle názvu a žánru filmu. V další části se podíváte na to, jak do modelu přidat vlastnost Movie
a jak přidat inicializátor, který automaticky vytvoří testovací databázi.