Badanie metod akcji i widoków kontrolera filmu

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.

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.

EditLink_sm

Link Edit został wygenerowany przez metodę Html.ActionLink w widoku Views\Movies\Index.cshtml :

@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html.ActionLink

Obiekt Html jest pomocnika uwidocznionego przy użyciu właściwości w klasie bazowej System.Web.Mvc.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 (ustanowiona w pliku App_Start\RouteConfig.cs) 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. Sprawdź poniższy kod z pliku App_Start\RouteConfig.cs .

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", 
            id = UrlParameter.Optional }
    );
}

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.

EditQueryString

Movies Otwórz kontroler. Poniżej przedstawiono dwie Edit metody akcji.

//
// GET: /Movies/Edit/5

public ActionResult Edit(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    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 HttpGetEdit pobiera parametr identyfikatora filmu, wyszukuje film przy użyciu metody Entity Framework Find i zwraca wybrany film do widoku Edycja. Parametr ID określa wartość domyślną zero, jeśli Edit metoda jest wywoływana bez parametru. Jeśli nie można odnaleźć filmu, zwracana jest metoda HttpNotFound . 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>

@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>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

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 renderuje 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 dla elementu formularza jest pokazany poniżej.

<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-date="The field ReleaseDate must be a date." 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="2.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>

<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 MVC ASP.NET przyjmuje opublikowane wartości formularza i tworzy Movie obiekt, który jest przekazywany jako movie parametr. Metoda ModelState.IsValid sprawdza, czy dane przesłane w formularzu mogą służyć do modyfikowania (edytowania lub aktualizowania) Movie obiektu. Jeśli dane są prawidłowe, dane filmu są zapisywane w Movies kolekcji db(MovieDBContext wystąpienia). Nowe dane filmu są zapisywane w bazie danych przez wywołanie SaveChanges metody MovieDBContext. Po zapisaniu danych kod przekierowuje użytkownika do Index metody MoviesController akcji klasy , która wyświetla kolekcję filmów, w tym wprowadzone zmiany.

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.

abcNotValid

Uwaga

Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla punktu dziesiętnego, należy uwzględnić globalize.js i określone kultury/pliki globalize.cultures.js (z https://github.com/jquery/globalize ) i JavaScript do użycia .Globalize.parseFloat Poniższy kod przedstawia modyfikacje pliku Views\Movies\Edit.cshtml do pracy z kulturą "fr-FR":

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="~/Scripts/globalize.js"></script>
    <script src="~/Scripts/globalize.culture.fr-FR.js"></script>
    <script>
        $.validator.methods.number = function (value, element) {
            return this.optional(element) ||
                !isNaN(Globalize.parseFloat(value));
        }
        $(document).ready(function () {
            Globalize.culture('fr-FR');
        });
    </script>
    <script>
        jQuery.extend(jQuery.validator.methods, {    
            range: function (value, element, param) {        
                //Use the Globalization plugin to parse the value        
                var val = $.global.parseFloat(value);
                return this.optional(element) || (
                    val >= param[0] && val <= param[1]);
            }
        });

    </script>
}

Pole dziesiętne może wymagać przecinka, a nie przecinka dziesiętnego. W ramach tymczasowej poprawki można dodać element globalizacji do głównego pliku web.config projektów. Poniższy kod przedstawia element globalizacji z kulturą ustawioną na Stany Zjednoczone angielski.

<system.web>
    <globalization culture ="en-US" />
    <!--elements removed for clarity-->
  </system.web>

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 i nie modyfikuje utrwalone dane.

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 wprowadzić, 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)); 
}

Powyższy s => s.Title kod jest wyrażeniem lambda. Lambdy są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where używana w powyższym kodzie. 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 zapytania, 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 polecenie Dodaj widok. W oknie dialogowym Dodawanie widoku określ, że obiekt ma zostać przekazany Movie do szablonu widoku jako jego klasa modelu. Na liście szablonów szkieletu wybierz pozycję Lista, a następnie kliknij przycisk Dodaj.

AddSearchView

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 Studio automatycznie wygenerował (szkielet) niektóre domyślne znaczniki w widoku. Tworzenie szkieletu spowodowało utworzenie formularza HTML. Przeanalizowała klasę Movie i utworzyła kod umożliwiający renderowanie <label> elementów dla każdej właściwości klasy. Na poniższej liście przedstawiono wygenerowany widok Tworzenia:

@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 do adresu URL. Zostaną wyświetlone przefiltrowane filmy.

SearchQryStr

Jeśli zmienisz podpis SearchIndex metody na parametr o nazwie id, id parametr będzie zgodny z symbolem {id} zastępczym dla tras domyślnych ustawionych w pliku Global.asax .

{controller}/{action}/{id}

Oryginalna SearchIndex metoda wygląda następująco:

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); 
}

Zmodyfikowana SearchIndex metoda będzie wyglądać następująco:

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.

SearchRouteData

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 podpis metody w celu przetestowania sposobu przekazywania parametru SearchIndex identyfikatora powiązanego z trasą, zmień go z powrotem, aby SearchIndex metoda pobierała 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 i zaraz po @Html.ActionLink("Create New", "Create")pliku dodaj następujące polecenie:

@using (Html.BeginForm()){    
         <p> Title: @Html.TextBox("SearchString")<br />  
         <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 opublikowanie formularza, gdy użytkownik prześle formularz, klikając przycisk Filtr .

Uruchom aplikację i spróbuj wyszukać film.

Zrzut ekranu przedstawiający uruchamianie aplikacji i próby wyszukania filmu.

Nie ma HttpPost przeciążenia SearchIndex metody . Nie potrzebujesz jej, ponieważ metoda nie zmienia stanu aplikacji, tylko 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>"; 
}

SearchPostGhost

Jednak nawet jeśli dodasz tę HttpPost wersję metody, istnieje ograniczenie dotyczące sposobu implementacji tego wszystkiego SearchIndex . 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ą przefiltrowaną listę filmów. Zwróć uwagę, że adres URL żądania HTTP POST jest taki sam jak adres URL żądania GET (localhost:xxxxx/Movies/SearchIndex) — w samym adresie URL nie ma żadnych informacji dotyczących wyszukiwania. 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 że powinny być kierowane do wersji SearchIndex HttpGet metody . Zastąp istniejącą metodę bez BeginForm parametrów następującym kodem:

@using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get))

BeginFormPost_SM

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 .

SearchIndexWithGetURL

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, a mianowicie 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 nie jest on pusty, kod dodatkowo 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 pomocnika do pliku Views\Movies\SearchIndex.cshtml tuż przed pomocnikiemTextBox. Ukończona adiustacja jest pokazana poniżej:

<p> 
    @Html.ActionLink("Create New", "Create") 
    @using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get)){     
         <p>Genre: @Html.DropDownList("movieGenre", "All")   
           Title: @Html.TextBox("SearchString")   
         <input type="submit" value="Filter" /></p> 
        } 
</p>

Uruchom aplikację i przejdź do folderu /Movies/SearchIndex. Spróbuj wyszukać według gatunku, nazwy filmu i obu kryteriów.

Zrzut ekranu przedstawiający uruchamianie aplikacji i próby wyszukania według nazwy filmu gatunkowego i obu kryteriów.

W tej sekcji przeanalizowano 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.