Badanie metod edycji i widoku edycji (C#)
Autor : Rick Anderson
Uwaga
Zaktualizowana wersja tego samouczka jest dostępna tutaj, która używa ASP.NET MVC 5 i Visual Studio 2013. Jest ona bezpieczniejsza, znacznie prostsza do naśladowania i demonstruje więcej funkcji.
Ten samouczek zawiera podstawowe informacje na temat tworzenia aplikacji internetowej MVC ASP.NET przy użyciu programu Microsoft Visual Web Developer 2010 Express z dodatkiem Service Pack 1, który jest bezpłatną wersją programu Microsoft Visual Studio. Przed rozpoczęciem upewnij się, że zostały zainstalowane wymagania wstępne wymienione poniżej. Wszystkie te elementy można zainstalować, klikając następujący link: Instalator platformy sieci Web. Alternatywnie można osobno zainstalować wymagania wstępne, korzystając z następujących linków:
- Wymagania wstępne programu Visual Studio Web Developer Express SP1
- ASP.NET aktualizacji narzędzi MVC 3
- SQL Server Compact 4.0 (środowisko uruchomieniowe i obsługa narzędzi)
Jeśli używasz programu Visual Studio 2010 zamiast Visual Web Developer 2010, zainstaluj wymagania wstępne, klikając następujący link: Wymagania wstępne programu Visual Studio 2010.
Projekt Visual Web Developer z kodem źródłowym języka C# jest dostępny do dołączenia do tego tematu. Pobierz wersję języka C#. Jeśli wolisz język Visual Basic, przejdź do wersji Visual Basic tego samouczka.
W tej sekcji zapoznasz się z wygenerowanymi metodami akcji i widokami kontrolera filmu. Następnie dodasz stronę wyszukiwania niestandardowego.
Uruchom aplikację i przejdź do Movies
kontrolera, dołączając ciąg /Movies do adresu URL na pasku adresu przeglądarki. Przytrzymaj wskaźnik myszy na linku Edytuj , aby wyświetlić adres URL, z którym się łączy.
Link Edit został wygenerowany przez metodę Html.ActionLink
w widoku Views\Movies\Index.cshtml :
@Html.ActionLink("Edit", "Edit", new { id=item.ID })
Obiekt Html
jest pomocnikiem uwidocznianym przy użyciu właściwości w klasie bazowej WebViewPage
. ActionLink
Metoda pomocnika ułatwia dynamiczne generowanie hiperlinków HTML, które łączą się z metodami akcji na kontrolerach. Pierwszym argumentem ActionLink
metody jest tekst linku do renderowania (na przykład <a>Edit Me</a>
). Drugim argumentem jest nazwa metody akcji do wywołania. Ostatnim argumentem jest anonimowy obiekt , który generuje dane trasy (w tym przypadku identyfikator 4).
Wygenerowany link pokazany na poprzedniej ilustracji to http://localhost:xxxxx/Movies/Edit/4
. Trasa domyślna przyjmuje wzorzec {controller}/{action}/{id}
adresu URL . W związku z tym ASP.NET przekłada się http://localhost:xxxxx/Movies/Edit/4
na żądanie do Edit
metody Movies
akcji kontrolera z parametrem ID
równym 4.
Parametry metody akcji można również przekazać przy użyciu ciągu zapytania. Na przykład adres URL http://localhost:xxxxx/Movies/Edit?ID=4
przekazuje również parametr ID
4 do Edit
metody Movies
akcji kontrolera.
Movies
Otwórz kontroler. Poniżej przedstawiono dwie Edit
metody akcji.
//
// GET: /Movies/Edit/5
public ActionResult Edit(int id)
{
Movie movie = db.Movies.Find(id);
return View(movie);
}
//
// POST: /Movies/Edit/5
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
Zwróć uwagę, że druga Edit
metoda akcji jest poprzedzona atrybutem HttpPost
. Ten atrybut określa, że przeciążenie Edit
metody może być wywoływane tylko dla żądań POST. Atrybut można zastosować HttpGet
do pierwszej metody edycji, ale nie jest to konieczne, ponieważ jest to ustawienie domyślne. (Odwołujemy się do metod akcji, które są niejawnie przypisywane HttpGet
atrybut jako HttpGet
metody).
Metoda HttpGet
Edit
pobiera parametr identyfikatora filmu, wyszukuje film przy użyciu metody Entity Framework Find
i zwraca wybrany film do widoku Edycja. Kiedy system tworzenia szkieletów utworzył widok Edycja, zbadał klasę Movie
i utworzył kod do renderowania <label>
i <input>
elementów dla każdej właściwości klasy. W poniższym przykładzie pokazano wygenerowany widok Edycji:
@model MvcMovie.Models.Movie
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ReleaseDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ReleaseDate)
@Html.ValidationMessageFor(model => model.ReleaseDate)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Genre)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Genre)
@Html.ValidationMessageFor(model => model.Genre)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Zwróć uwagę, że szablon widoku ma instrukcję @model MvcMovie.Models.Movie
w górnej części pliku — określa, że widok oczekuje modelu dla szablonu widoku typu Movie
.
Kod szkieletowy używa kilku metod pomocnika w celu usprawnienia znaczników HTML. Pomocnik Html.LabelFor
wyświetla nazwę pola ("Title", "ReleaseDate", "Genre" lub "Price"). Pomocnik Html.EditorFor
wyświetla element HTML <input>
. Pomocnik Html.ValidationMessageFor
wyświetla wszystkie komunikaty sprawdzania poprawności skojarzone z tą właściwością.
Uruchom aplikację i przejdź do adresu URL /Movies . Kliknij link Edytuj . W przeglądarce wyświetl źródło strony. Kod HTML na stronie wygląda podobnie do poniższego przykładu. (Znaczniki menu zostały wykluczone w celu zachowania przejrzystości).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="/Scripts/modernizr-1.7.min.js" type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>MVC Movie App</h1>
</div>
...
</header>
<section id="main">
<h2>Edit</h2>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<form action="/Movies/Edit/4" method="post"> <fieldset>
<legend>Movie</legend>
<input data-val="true" data-val-number="The field ID must be a number."
data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" />
<div class="editor-label">
<label for="Title">Title</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Title" name="Title" type="text" value="Rio Bravo" />
<span class="field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="ReleaseDate">ReleaseDate</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="The ReleaseDate field is required."
id="ReleaseDate" name="ReleaseDate" type="text" value="4/15/1959 12:00:00 AM" />
<span class="field-validation-valid" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="Genre">Genre</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Genre" name="Genre" type="text" value="Western" />
<span class="field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="Price">Price</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-number="The field Price must be a number."
data-val-required="The Price field is required." id="Price" name="Price" type="text" value="9.99" />
<span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</form>
<div>
<a href="/Movies">Back to List</a>
</div>
</section>
<footer>
</footer>
</div>
</body>
</html>
<input>
Elementy znajdują się w elemecie HTML<form>
, którego action
atrybut jest ustawiony na publikowanie w adresie URL /Movies/Edit. Dane formularza zostaną opublikowane na serwerze po kliknięciu przycisku Edytuj .
Przetwarzanie żądania POST
Na poniższej HttpPost
liście przedstawiono wersję Edit
metody akcji.
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
Powiązanie modelu platformy ASP.NET przyjmuje opublikowane wartości formularza i tworzy Movie
obiekt przekazywany jako movie
parametr. Zaewidencjonuj ModelState.IsValid
kod weryfikuje, czy dane przesłane w formularzu mogą służyć do modyfikowania Movie
obiektu. Jeśli dane są prawidłowe, kod zapisuje dane filmu w Movies
kolekcji MovieDBContext
wystąpienia. Następnie kod zapisuje nowe dane filmu w bazie danych przez wywołanie SaveChanges
metody MovieDBContext
, która utrwala zmiany w bazie danych. Po zapisaniu danych kod przekierowuje użytkownika do Index
metody MoviesController
akcji klasy , co powoduje wyświetlenie zaktualizowanego filmu na liście filmów.
Jeśli wartości opublikowane nie są prawidłowe, są odtwarzane ponownie w formularzu. Pomocnicy Html.ValidationMessageFor
w szablonie widoku Edit.cshtml dbają o wyświetlanie odpowiednich komunikatów o błędach.
Uwaga dotycząca ustawień regionalnych Jeśli zwykle pracujesz z ustawieniami regionalnymi innymi niż angielski, zobacz Obsługa ASP.NET walidacji MVC 3 przy użyciu ustawień regionalnych innych niż angielski.
Zwiększenie niezawodności metody edycji
HttpGet
Edit
Metoda wygenerowana przez system tworzenia szkieletów nie sprawdza, czy identyfikator przekazany do niego jest prawidłowy. Jeśli użytkownik usunie segment IDENTYFIKATORa z adresu URL (http://localhost:xxxxx/Movies/Edit
), zostanie wyświetlony następujący błąd:
Użytkownik może również przekazać identyfikator, który nie istnieje w bazie danych, na przykład http://localhost:xxxxx/Movies/Edit/1234
. Aby rozwiązać to ograniczenie, możesz wprowadzić dwie zmiany w metodzie HttpGet
Edit
akcji. Najpierw zmień parametr tak ID
, aby miał domyślną wartość zero, gdy identyfikator nie jest jawnie przekazywany. Możesz również sprawdzić, czy Find
metoda rzeczywiście znalazła film przed zwróceniem obiektu filmu do szablonu widoku. Zaktualizowana Edit
metoda jest pokazana poniżej.
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
Jeśli film nie zostanie znaleziony, zostanie wywołana HttpNotFound
metoda .
HttpGet
Wszystkie metody są zgodne z podobnym wzorcem. Pobierają obiekt filmu (lub listę obiektów, w przypadku Index
), a następnie przekazują model do widoku. Metoda Create
przekazuje pusty obiekt filmu do widoku Utwórz. Wszystkie metody, które tworzą, edytują, usuwają lub w inny sposób modyfikują dane w HttpPost
przeciążeniu metody . Modyfikowanie danych w metodzie HTTP GET jest zagrożeniem bezpieczeństwa, zgodnie z opisem we wpisie we wpisie w blogu ASP.NET porada MVC nr 46 — nie używaj linków usuwania, ponieważ tworzą one luki w zabezpieczeniach. Modyfikowanie danych w metodzie GET narusza również najlepsze rozwiązania HTTP i wzorzec REST architektury, który określa, że żądania GET nie powinny zmieniać stanu aplikacji. Innymi słowy wykonywanie operacji GET powinno być bezpieczną operacją, która nie ma skutków ubocznych.
Dodawanie metody wyszukiwania i widoku wyszukiwania
W tej sekcji dodasz metodę SearchIndex
akcji, która umożliwia wyszukiwanie filmów według gatunku lub nazwy. Będzie to dostępne przy użyciu adresu URL /Movies/SearchIndex . Żądanie wyświetli formularz HTML zawierający elementy wejściowe, które użytkownik może wypełnić, aby wyszukać film. Gdy użytkownik prześle formularz, metoda akcji pobierze wartości wyszukiwania opublikowane przez użytkownika i użyje wartości do przeszukania bazy danych.
Wyświetlanie formularza indeksu wyszukiwania
Zacznij od dodania SearchIndex
metody akcji do istniejącej MoviesController
klasy. Metoda zwróci widok zawierający formularz HTML. Oto kod:
public ActionResult SearchIndex(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);
}
Pierwszy wiersz SearchIndex
metody tworzy następujące zapytanie LINQ w celu wybrania filmów:
var movies = from m in db.Movies
select m;
Zapytanie jest zdefiniowane w tym momencie, ale nie zostało jeszcze uruchomione względem magazynu danych.
searchString
Jeśli parametr zawiera ciąg, zapytanie filmów jest modyfikowane w celu filtrowania wartości ciągu wyszukiwania przy użyciu następującego kodu:
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikowania przez wywołanie metody, takiej jak Where
lub OrderBy
. Zamiast tego wykonanie zapytania jest odroczone, co oznacza, że obliczanie wyrażenia jest opóźnione do momentu, gdy jego zrealizowana wartość zostanie rzeczywiście iterowana lub ToList
wywoływana jest metoda. W przykładzie SearchIndex
zapytanie jest wykonywane w widoku SearchIndex. Aby uzyskać więcej informacji na temat odroczonego wykonywania zapytań, zobacz Wykonywanie zapytań.
Teraz możesz zaimplementować SearchIndex
widok, który wyświetli formularz użytkownikowi. Kliknij prawym przyciskiem myszy wewnątrz SearchIndex
metody, a następnie kliknij pozycję Dodaj widok. W oknie dialogowym Dodawanie widoku określ, że obiekt zostanie przekazany Movie
do szablonu widoku jako jego klasa modelu. Na liście szablonów szkieletu wybierz pozycję Lista, a następnie kliknij przycisk Dodaj.
Po kliknięciu przycisku Dodaj zostanie utworzony szablon widok Views\Movies\SearchIndex.cshtml . Ponieważ wybrano pozycję Lista na liście szablonów szkieletu , program Visual Web Developer automatycznie wygenerował (szkielet) część domyślną zawartości w widoku. Tworzenie szkieletu spowodowało utworzenie formularza HTML. Przeanalizowała klasę Movie
i utworzyła kod, aby renderować <label>
elementy dla każdej właściwości klasy. Na poniższej liście przedstawiono widok Utwórz, który został wygenerowany:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "SearchIndex";
}
<h2>SearchIndex</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Title
</th>
<th>
ReleaseDate
</th>
<th>
Genre
</th>
<th>
Price
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
Uruchom aplikację i przejdź do folderu /Movies/SearchIndex. Dołącz ciąg zapytania, taki jak ?searchString=ghost
adres URL. Zostaną wyświetlone przefiltrowane filmy.
Jeśli zmienisz podpis SearchIndex
metody na parametr o nazwie id
, id
parametr będzie zgodny {id}
z symbolem zastępczym dla tras domyślnych ustawionych w pliku Global.asax .
{controller}/{action}/{id}
Zmodyfikowana metoda wygląda następująco SearchIndex
:
public ActionResult SearchIndex(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);
}
Teraz możesz przekazać tytuł wyszukiwania jako dane trasy (segment adresu URL) zamiast jako wartość ciągu zapytania.
Nie można jednak oczekiwać, że użytkownicy będą modyfikować adres URL za każdym razem, gdy chcą wyszukać film. Teraz dodasz interfejs użytkownika, aby ułatwić filtrowanie filmów. Jeśli zmieniono sygnaturę metody, aby przetestować sposób przekazywania parametru SearchIndex
identyfikatora powiązanego z trasą, zmień go z powrotem, aby SearchIndex
metoda przyjmuje parametr ciągu o nazwie searchString
:
public ActionResult SearchIndex(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);
}
Otwórz plik Views\Movies\SearchIndex.cshtml , a tuż po @Html.ActionLink("Create New", "Create")
pliku dodaj następujące elementy:
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" /></p>
}
Poniższy przykład przedstawia część pliku Views\Movies\SearchIndex.cshtml z dodanym znacznikiem filtrowania.
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "SearchIndex";
}
<h2>SearchIndex</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString") <br />
<input type="submit" value="Filter" /></p>
}
</p>
Pomocnik Html.BeginForm
tworzy tag otwierający <form>
. Pomocnik Html.BeginForm
powoduje, że formularz zostanie przesłany do samego siebie, gdy użytkownik prześle formularz, klikając przycisk Filtruj .
Uruchom aplikację i spróbuj wyszukać film.
Nie HttpPost
ma przeciążenia SearchIndex
metody. Nie jest to potrzebne, ponieważ metoda nie zmienia stanu aplikacji, po prostu filtrując dane.
Możesz dodać następującą HttpPost SearchIndex
metodę. W takim przypadku wywołanie akcji będzie zgodne z HttpPost SearchIndex
metodą, a HttpPost SearchIndex
metoda zostanie uruchomiona, jak pokazano na poniższej ilustracji.
[HttpPost]
public string SearchIndex(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>";
}
Jednak nawet jeśli dodasz tę HttpPost
wersję metody, istnieje ograniczenie sposobu, w jaki wszystkie te elementy SearchIndex
zostały zaimplementowane. Załóżmy, że chcesz dodać zakładkę do określonego wyszukiwania lub chcesz wysłać link do znajomych, którzy mogą kliknąć, aby wyświetlić tę samą filtrowaną listę filmów. Zwróć uwagę, że adres URL żądania HTTP POST jest taki sam jak adres URL żądania GET (localhost:xxxxx/Movies/SearchIndex) — nie ma żadnych informacji wyszukiwania w samym adresie URL. W tej chwili informacje o ciągu wyszukiwania są wysyłane do serwera jako wartość pola formularza. Oznacza to, że nie można przechwycić tych informacji wyszukiwania do zakładki ani wysłać do znajomych w adresie URL.
Rozwiązaniem jest użycie przeciążenia BeginForm
, które określa, że żądanie POST powinno dodać informacje wyszukiwania do adresu URL i które powinno być kierowane do wersji SearchIndex
HttpGet metody . Zastąp istniejącą metodę bez BeginForm
parametrów następującymi elementami:
@using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get))
Teraz po przesłaniu wyszukiwania adres URL zawiera ciąg zapytania wyszukiwania. Wyszukiwanie spowoduje również przejście do HttpGet SearchIndex
metody akcji, nawet jeśli masz metodę HttpPost SearchIndex
.
Dodawanie wyszukiwania według gatunku
Jeśli dodano HttpPost
wersję SearchIndex
metody, usuń ją teraz.
Następnie dodasz funkcję umożliwiającą użytkownikom wyszukiwanie filmów według gatunku. Zastąp metodę SearchIndex
poniższym kodem:
public ActionResult SearchIndex(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))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == movieGenre));
}
}
Ta wersja SearchIndex
metody przyjmuje dodatkowy parametr, czyli movieGenre
. Kilka pierwszych wierszy kodu tworzy List
obiekt do przechowywania gatunków filmów z bazy danych.
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
Kod używa AddRange
metody kolekcji ogólnej List
, aby dodać wszystkie odrębne gatunki do listy. (Bez Distinct
modyfikatora zostaną dodane zduplikowane gatunki — na przykład komedia zostanie dodana dwa razy w naszym przykładzie). Następnie kod przechowuje listę gatunków w ViewBag
obiekcie.
Poniższy kod pokazuje, jak sprawdzić movieGenre
parametr. Jeśli kod nie jest pusty, ogranicza zapytanie filmów, aby ograniczyć wybrane filmy do określonego gatunku.
if (string.IsNullOrEmpty(movieGenre))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == movieGenre));
}
Dodawanie znaczników do widoku SearchIndex w celu obsługi wyszukiwania według gatunku
Html.DropDownList
Dodaj pomocnik do pliku Views\Movies\SearchIndex.cshtml tuż przed pomocnikiemTextBox
. Ukończone znaczniki są wyświetlane poniżej:
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p>Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" /></p>
}
</p>
Uruchom aplikację i przejdź do /Movies/SearchIndex. Spróbuj wyszukać według gatunku, według nazwy filmu i według obu kryteriów.
W tej sekcji zbadano metody akcji CRUD i widoki wygenerowane przez platformę. Utworzono metodę akcji wyszukiwania i widok, która umożliwia użytkownikom wyszukiwanie według tytułu filmu i gatunku. W następnej sekcji dowiesz się, jak dodać właściwość do Movie
modelu i jak dodać inicjator, który automatycznie utworzy testową bazę danych.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla