Freigeben über


Untersuchen der Aktionsmethoden und -ansichten für den Filmcontroller

von Rick Anderson

Hinweis

Hier ist eine aktualisierte Version dieses Lernprogramms verfügbar, die ASP.NET MVC 5 und Visual Studio 2013 verwendet. Es ist sicherer, viel einfacher zu folgen und zeigt weitere Features.

In diesem Abschnitt untersuchen Sie die generierten Aktionsmethoden und -ansichten für den Filmcontroller. Anschließend fügen Sie eine benutzerdefinierte Suchseite hinzu.

Führen Sie die Anwendung aus, und navigieren Sie zum Movies Controller, indem Sie /Movies an die URL in der Adressleiste Ihres Browsers anfügen. Halten Sie den Mauszeiger über einen Bearbeitungslink , um die URL anzuzeigen, mit der sie verknüpft ist.

EditLink_sm

Der Link "Bearbeiten" wurde von der Html.ActionLink Methode in der Ansicht "Views\Movies\Index.cshtml " generiert:

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

Html.ActionLink

Das Html Objekt ist ein Hilfsprogramm, das mithilfe einer Eigenschaft in der System.Web.Mvc.WebViewPage-Basisklasse verfügbar gemacht wird. Die ActionLink Methode des Hilfsprogramm erleichtert das dynamische Generieren von HTML-Links, die mit Aktionsmethoden auf Controllern verknüpft sind. Das erste Argument für die ActionLink Methode ist der zu renderde Verknüpfungstext (z. B <a>Edit Me</a>. ). Das zweite Argument ist der Name der aufzurufenden Aktionsmethode. Das letzte Argument ist ein anonymes Objekt , das die Routendaten generiert (in diesem Fall die ID von 4).

Der generierte Link, der in der vorherigen Abbildung angezeigt wird, ist http://localhost:xxxxx/Movies/Edit/4. Die In App_Start\RouteConfig.cs festgelegte Standardroute verwendet das URL-Muster{controller}/{action}/{id}. Daher wird ASP.NET in eine Anforderung an die Aktionsmethode des Movies Controllers mit dem Parameter ID gleich 4 übersetzthttp://localhost:xxxxx/Movies/Edit/4.Edit Überprüfen Sie den folgenden Code aus der Datei 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 }
    );
}

Sie können auch Aktionsmethodenparameter mithilfe einer Abfragezeichenfolge übergeben. Die URL http://localhost:xxxxx/Movies/Edit?ID=4 übergibt beispielsweise auch den Parameter ID 4 an die Edit Aktionsmethode des Movies Controllers.

EditQueryString

Öffnen Sie den Movies Controller. Die beiden Edit Aktionsmethoden sind unten dargestellt.

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

Beachten Sie, dass der zweiten Edit-Aktionsmethode das HttpPost-Attribut vorangestellt ist. Dieses Attribut gibt an, dass die Überladung der Edit Methode nur für POST-Anforderungen aufgerufen werden kann. Sie können das HttpGet Attribut auf die erste Bearbeitungsmethode anwenden, dies ist jedoch nicht erforderlich, da es sich um die Standardeinstellung ist. (Wir verweisen auf Aktionsmethoden, die dem HttpGet Attribut implizit als HttpGet Methoden zugewiesen werden.)

Die HttpGet Edit Methode verwendet den Film-ID-Parameter, sucht den Film mithilfe der Entity Framework-Methode Find und gibt den ausgewählten Film an die Bearbeitungsansicht zurück. Der ID-Parameter gibt einen Standardwert von Null an, wenn die Edit Methode ohne Parameter aufgerufen wird. Wenn ein Film nicht gefunden werden kann, wird HttpNotFound zurückgegeben. Als das Gerüstsystem die Bearbeitungsansicht erstellt hat, wurde die Movie-Klasse überprüft und Code zum Rendern der <label>- und <input>-Elemente für jede Eigenschaft der Klasse erstellt. Das folgende Beispiel zeigt die Bearbeitungsansicht, die generiert wurde:

@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")
}

Beachten Sie, dass die Ansichtsvorlage oben in der Datei eine @model MvcMovie.Models.Movie Anweisung aufweist . Dies gibt an, dass die Ansicht das Modell für die Ansichtsvorlage vom Typ Movieaufweist.

Der Gerüstcode verwendet mehrere Hilfsmethoden , um das HTML-Markup zu optimieren. Das Html.LabelFor Hilfsprogramm zeigt den Namen des Felds an ("Titel", "ReleaseDate", "Genre" oder "Preis"). Das Html.EditorFor Hilfsprogramm rendert ein HTML-Element <input> . Das Html.ValidationMessageFor Hilfsprogramm zeigt alle Überprüfungsmeldungen an, die dieser Eigenschaft zugeordnet sind.

Führen Sie die Anwendung aus, und navigieren Sie zur URL "/Movies ". Klicken Sie auf einen Link Bearbeiten. Zeigen Sie im Browser den Quelltext für die Seite an. Der HTML-Code für das Formularelement wird unten angezeigt.

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

Die <input> Elemente befinden sich in einem HTML-Element <form> , dessen action Attribut auf die URL "/Movies/Edit " festgelegt ist. Die Formulardaten werden auf dem Server gepostet, wenn auf die Schaltfläche "Bearbeiten " geklickt wird.

Verarbeiten der POST-Anforderung

Die folgende Liste zeigt die HttpPost-Version der Edit-Aktionsmethode.

[HttpPost] 
public ActionResult Edit(Movie movie)  
{ 
    if (ModelState.IsValid)  
    { 
        db.Entry(movie).State = EntityState.Modified; 
        db.SaveChanges(); 
        return RedirectToAction("Index"); 
    } 
    return View(movie); 
}

Der ASP.NET MVC-Modellordner verwendet die geposteten Formularwerte und erstellt ein Movie Objekt, das als movie Parameter übergeben wird. Die ModelState.IsValid-Methode stellt sicher, dass die im Formular übermittelten Daten verwendet werden können, um ein Movie-Objekt zu ändern (bearbeiten oder aktualisieren). Wenn die Daten gültig sind, werden die Filmdaten in der Movies Sammlung der db(MovieDBContext Instanz gespeichert. Die neuen Filmdaten werden in der Datenbank gespeichert, indem die SaveChanges Methode von MovieDBContextaufgerufen wird. Nach dem Speichern der Daten leitet der Code den Benutzer an die Index Aktionsmethode der MoviesController Klasse weiter, die die Filmsammlung anzeigt, einschließlich der soeben vorgenommenen Änderungen.

Wenn die geposteten Werte ungültig sind, werden sie im Formular erneut angezeigt. Die Html.ValidationMessageFor Hilfsprogramme in der Ansichtsvorlage "Edit.cshtml " kümmern sich um die Anzeige geeigneter Fehlermeldungen.

abcNotValid

Hinweis

um die jQuery-Überprüfung für nicht englische Gebietsschemas zu unterstützen, die ein Komma (",") für einen Dezimalkomma verwenden, müssen Sie globalize.js und Ihre spezifischen Kulturen/globalize.cultures.js Datei(aus https://github.com/jquery/globalize ) und JavaScript verwenden, um sie zu verwendenGlobalize.parseFloat. Der folgende Code zeigt die Änderungen an der Datei Views\Movies\Edit.cshtml für die Arbeit mit der 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>
}

Für das Dezimalfeld ist möglicherweise ein Komma erforderlich, kein Dezimalkomma. Als temporärer Fix können Sie das Globalisierungselement zur Stammdatei "web.config" für Projekte hinzufügen. Der folgende Code zeigt das Globalisierungselement, bei dem die Kultur auf USA Englisch festgelegt ist.

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

HttpGet Alle Methoden folgen einem ähnlichen Muster. Sie erhalten ein Filmobjekt (oder eine Liste von Objekten im Fall von Index), und übergeben das Modell an die Ansicht. Die Create Methode übergibt ein leeres Filmobjekt an die Create-Ansicht. Alle Methoden, die Daten erstellen, bearbeiten, löschen oder in beliebiger Weise ändern, nutzen dazu die HttpPost-Überladung der Methode. Das Ändern von Daten in einer HTTP GET-Methode ist ein Sicherheitsrisiko. Das Ändern von Daten in einer GET-Methode verstößt auch gegen bewährte HTTP-Methoden und das Architektur-REST-Muster, das angibt, dass GET-Anforderungen den Zustand Ihrer Anwendung nicht ändern sollten. Die Durchführung eines GET-Vorgangs sollte also eine sichere Operation sein, die keine Nebenwirkungen hat und die permanenten Daten nicht ändert.

Hinzufügen einer Suchmethode und Suchansicht

In diesem Abschnitt fügen Sie eine SearchIndex Aktionsmethode hinzu, mit der Sie Filme nach Genre oder Name durchsuchen können. Dies ist mit der URL "/Movies/SearchIndex " verfügbar. Die Anforderung zeigt ein HTML-Formular an, das Eingabeelemente enthält, die ein Benutzer eingeben kann, um nach einem Film zu suchen. Wenn ein Benutzer das Formular sendet, erhält die Aktionsmethode die vom Benutzer geposteten Suchwerte und verwendet die Werte, um die Datenbank zu durchsuchen.

Anzeigen des SearchIndex-Formulars

Fügen Sie zunächst der vorhandenen MoviesController Klasse eine SearchIndex Aktionsmethode hinzu. Die Methode gibt eine Ansicht zurück, die ein HTML-Formular enthält. Der Code lautet wie folgt:

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

Die erste Zeile der SearchIndex Methode erstellt die folgende LINQ-Abfrage , um die Filme auszuwählen:

var movies = from m in db.Movies 
             select m;

Die Abfrage ist an diesem Punkt definiert, wurde jedoch noch nicht für den Datenspeicher ausgeführt.

Wenn der searchString Parameter eine Zeichenfolge enthält, wird die Filmabfrage mit dem folgenden Code geändert, um nach dem Wert der Suchzeichenfolge zu filtern:

if (!String.IsNullOrEmpty(searchString)) 
{ 
    movies = movies.Where(s => s.Title.Contains(searchString)); 
}

Der Code s => s.Title oben ist ein Lambdaausdruck. Lambdas werden in methodenbasierten LINQ-Abfragen als Argumente für Standardabfragenoperatormethoden verwendet, z. B. die Where-Methode , die im obigen Code verwendet wird. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert sind oder durch Aufrufen einer Methode wie Where oder OrderBy. Stattdessen wird die Abfrageausführung verzögert. Dies bedeutet, dass die Auswertung eines Ausdrucks verzögert wird, bis der realisierte Wert tatsächlich durchlaufen wird oder die ToList Methode aufgerufen wird. SearchIndex Im Beispiel wird die Abfrage in der SearchIndex-Ansicht ausgeführt. Weitere Informationen zur verzögerten Abfrageausführung finden Sie unter Abfrageausführung.

Jetzt können Sie die Ansicht implementieren, in der SearchIndex das Formular für den Benutzer angezeigt wird. Klicken Sie mit der rechten Maustaste in die SearchIndex Methode, und klicken Sie dann auf "Ansicht hinzufügen". Geben Sie im Dialogfeld "Ansicht hinzufügen" an, dass Sie ein Movie Objekt als Modellklasse an die Ansichtsvorlage übergeben möchten. Wählen Sie in der Gerüstvorlagenliste "Liste" die Option "Liste" aus, und klicken Sie dann auf "Hinzufügen".

AddSearchView

Wenn Sie auf die Schaltfläche "Hinzufügen " klicken, wird die Ansichtsvorlage "Views\Movies\SearchIndex.cshtml " erstellt. Da Sie "Liste" in der Vorlagenliste "Gerüst" ausgewählt haben, generiert Visual Studio automatisch ein Standardmarkup in der Ansicht (Gerüst). Das Gerüst hat ein HTML-Formular erstellt. Es hat die Movie Klasse untersucht und Code erstellt, um Elemente für jede Eigenschaft der Klasse zu rendern <label> . Die folgende Auflistung zeigt die Erstellungsansicht, die generiert wurde:

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

Führen Sie die Anwendung aus, und navigieren Sie zu /Movies/SearchIndex. Fügen Sie eine Abfragezeichenfolge wie ?searchString=ghost an die URL an. Die gefilterten Filme werden angezeigt.

SearchQryStr

Wenn Sie die Signatur der SearchIndex Methode so ändern, dass ein Parameter benannt idwird, entspricht der id Parameter dem {id} Platzhalter für die in der Datei "Global.asax " festgelegten Standardrouten.

{controller}/{action}/{id}

Die ursprüngliche SearchIndex Methode sieht wie folgt aus::

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

Die geänderte SearchIndex Methode würde wie folgt aussehen:

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

Sie können nun den Suchtitel als Routendaten (ein URL-Segment) anstatt als Wert einer Abfragezeichenfolge übergeben.

SearchRouteData

Sie können jedoch von den Benutzern nicht erwarten, dass sie jedes Mal die URL ändern, wenn sie nach einem Film suchen möchten. Jetzt fügen Sie eine Benutzeroberfläche hinzu, um ihnen beim Filtern von Filmen zu helfen. Wenn Sie die Signatur der SearchIndex Methode geändert haben, um zu testen, wie der routinggebundene ID-Parameter übergeben wird, ändern Sie ihn wieder, sodass die SearchIndex Methode einen Zeichenfolgenparameter namens :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); 
}

Öffnen Sie die Datei "Views\Movies\SearchIndex.cshtml ", und fügen Sie direkt danach @Html.ActionLink("Create New", "Create")Folgendes hinzu:

@using (Html.BeginForm()){    
         <p> Title: @Html.TextBox("SearchString")<br />  
         <input type="submit" value="Filter" /></p> 
        }

Das folgende Beispiel zeigt einen Teil der Datei Views\Movies\SearchIndex.cshtml mit dem hinzugefügten Filtermarkup.

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

Das Html.BeginForm Hilfsprogramm erstellt ein öffnende <form> Tag. Das Html.BeginForm Hilfsprogramm bewirkt, dass das Formular an sich selbst gepostet wird, wenn der Benutzer das Formular sendet, indem er auf die Schaltfläche "Filter " klickt.

Führen Sie die Anwendung aus, und suchen Sie nach einem Film.

Screenshot der Ausführung der Anwendung und Versuch, nach einem Film zu suchen.

Es gibt keine HttpPost Überladung der SearchIndex Methode. Sie benötigen sie nicht, da die Methode den Zustand der Anwendung nicht ändert, nur Daten zu filtern.

Sie können die folgende HttpPost SearchIndex-Methode hinzufügen. In diesem Fall stimmt der Aktionsaufrufer mit der HttpPost SearchIndex Methode überein, und die HttpPost SearchIndex Methode würde wie in der abbildung unten dargestellt ausgeführt.

[HttpPost] 
public string SearchIndex(FormCollection fc, string searchString) 
{ 
    return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>"; 
}

SearchPostGhost

Doch selbst wenn Sie diese HttpPost-Version der SearchIndex-Methode hinzufügen, gibt es eine Einschränkung für die gesamte Implementierung. Stellen Sie sich vor, Sie möchten eine bestimmte Suche als Favorit speichern oder einen Link an Freunde senden, auf den diese klicken können, um dieselbe gefilterte Liste von Filmen anzuzeigen. Beachten Sie, dass die URL für die HTTP POST-Anforderung mit der URL für die GET-Anforderung (localhost:xxxxx/Movies/SearchIndex) identisch ist – es gibt keine Suchinformationen in der URL selbst. Im Moment werden die Suchzeichenfolgeninformationen als Formularfeldwert an den Server gesendet. Dies bedeutet, dass Sie diese Suchinformationen nicht erfassen können, um eine Textmarke zu erstellen oder an Freunde in einer URL zu senden.

Die Lösung besteht darin, eine Überladung BeginForm zu verwenden, die angibt, dass die POST-Anforderung die Suchinformationen zur URL hinzufügen und an die HttpGet-Version der SearchIndex Methode weitergeleitet werden soll. Ersetzen Sie die vorhandene parameterlose BeginForm Methode durch Folgendes:

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

BeginFormPost_SM

Wenn Sie nun eine Suche übermitteln, enthält die URL eine Suchabfragezeichenfolge. Das Suchen wird auch an Aktionsmethode HttpGet SearchIndex übertragen, auch wenn Sie eine HttpPost SearchIndex-Methode haben.

SearchIndexWithGetURL

Hinzufügen der Suche nach Genre

Wenn Sie die HttpPost Version der SearchIndex Methode hinzugefügt haben, löschen Sie sie jetzt.

Als Nächstes fügen Sie ein Feature hinzu, mit dem Benutzer nach Filmen nach Genre suchen können. Ersetzen Sie die SearchIndex-Methode durch folgenden Code:

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

Diese Version der SearchIndex Methode akzeptiert einen zusätzlichen Parameter, nämlich movieGenre. In den ersten Codezeilen wird ein List Objekt erstellt, das Filmgenres aus der Datenbank enthält.

Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.

var GenreQry = from d in db.Movies 
                   orderby d.Genre 
                   select d.Genre;

Der Code verwendet die AddRange Methode der generischen List Auflistung, um alle unterschiedlichen Genres zur Liste hinzuzufügen. (Ohne den Distinct Modifizierer würden duplizierte Genres hinzugefügt , z. B. würde Komödie zweimal in unserem Beispiel hinzugefügt). Der Code speichert dann die Liste der Genres im ViewBag Objekt.

Der folgende Code zeigt, wie der movieGenre Parameter überprüft wird. Wenn sie nicht leer ist, schränkt der Code die Filmabfrage weiter ein, um die ausgewählten Filme auf das angegebene Genre zu beschränken.

if (string.IsNullOrEmpty(movieGenre)) 
        return View(movies); 
else 
{ 
    return View(movies.Where(x => x.Genre == movieGenre)); 
}

Hinzufügen von Markup zur SearchIndex-Ansicht zur Unterstützung der Suche nach Genre

Fügen Sie der Datei "Views\Movies\SearchIndex.cshtml" direkt vor dem TextBox Hilfsprogramm eine Html.DropDownList Hilfsfunktion hinzu. Das fertige Markup wird unten angezeigt:

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

Führen Sie die Anwendung aus, und navigieren Sie zu /Movies/SearchIndex. Probieren Sie eine Suche nach Genre, nach Filmname und nach beiden Kriterien aus.

Screenshot der Ausführung der Anwendung und Versuch, nach Genrefilmnamen und nach beiden Kriterien zu suchen.

In diesem Abschnitt haben Sie die CRUD-Aktionsmethoden und -ansichten untersucht, die vom Framework generiert wurden. Sie haben eine Suchaktionsmethode und -ansicht erstellt, mit der Benutzer nach Filmtitel und Genre suchen können. Im nächsten Abschnitt erfahren Sie, wie Sie dem Movie Modell eine Eigenschaft hinzufügen und einen Initialisierer hinzufügen, der automatisch eine Testdatenbank erstellt.