Suche

Hinweis

Eine aktualisierte Version dieses Tutorials ist hier mit der neuesten Version von Visual Studio verfügbar. Das neue Tutorial verwendet ASP.NET Core MVC, der viele Verbesserungen gegenüber diesem Tutorial bietet.

Dieses Tutorial vermittelt Informationen zu ASP.NET Core MVC mit Controllern und Ansichten. Razor Pages ist eine neue Alternative in ASP.NET Core, einem seitenbasierten Programmiermodell, das das Erstellen einer Webbenutzeroberfläche einfacher und produktiver macht. Es empfiehlt sich, dass Sie sich das Tutorial der Razor Pages vor der MVC-Version ansehen. Das Tutorial zu Razor Pages:

  • Ist einfacher zu befolgen.
  • Behandelt mehr Features.
  • Ist der bevorzugte Ansatz für die Entwicklung neuer Apps.

Hinzufügen einer Suchmethode und Suchansicht

In diesem Abschnitt fügen Sie der Aktionsmethode Suchfunktionen hinzu, mit der Index Sie Filme nach Genre oder Namen durchsuchen können.

Voraussetzungen

Um den Screenshots dieses Abschnitts zu entsprechen, müssen Sie die Anwendung (F5) ausführen und der Datenbank die folgenden Filme hinzufügen.

Titel Veröffentlichungsdatum Genre Preis
Ghostbusters 6/8/1984 Komödie 6,99
Ghostbuster II 6/16/1989 Komödie 6,99
Planet der Affen 3/27/1986 Action 5,99

Aktualisieren des Indexformulars

Aktualisieren Sie zunächst die Index Aktionsmethode auf die vorhandene MoviesController Klasse. Der Code lautet wie folgt:

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

Die erste Zeile der Index 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 aber noch nicht für die Datenbank ausgeführt.

Wenn der searchString Parameter eine Zeichenfolge enthält, wird die Movies-Abfrage geändert, um nach dem Wert der Suchzeichenfolge zu filtern, wobei der folgende Code verwendet wird:

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 Standardabfrageoperatormethoden wie die im obigen Code verwendete Where-Methode verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert sind oder wenn sie durch Aufrufen einer Methode wie Where oder OrderBygeändert werden. Stattdessen wird die Abfrageausführung zurückgestellt, was bedeutet, dass die Auswertung eines Ausdrucks verzögert wird, bis der realisierte Wert tatsächlich durchlaufen oder die ToList Methode aufgerufen wird. Search Im Beispiel wird die Abfrage in der Ansicht Index.cshtml ausgeführt. Weitere Informationen zur verzögerten Abfrageausführung finden Sie unter Abfrageausführung.

Hinweis

Die Contains-Methode wird für die Datenbank und nicht für den oben genannten c#-Code ausgeführt. In der Datenbank wird ContainsSQL LIKE zugeordnet, wobei die Groß-/Kleinschreibung nicht beachtet wird.

Jetzt können Sie die Index Ansicht aktualisieren, in der das Formular für den Benutzer angezeigt wird.

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

SearchQryStr

Wenn Sie die Signatur der Index Methode in einen Parameter namens idändern, entspricht der id Parameter dem {id} Platzhalter für die Standardrouten, die in der Datei App_Start\RouteConfig.cs festgelegt sind.

{controller}/{action}/{id}

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

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

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

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

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

Screenshot: Seite

Sie können jedoch von den Benutzern nicht erwarten, dass sie jedes Mal die URL ändern, wenn sie nach einem Film suchen möchten. Deshalb fügen Sie nun eine Benutzeroberflächenoption zum besseren Filtern von Filmen hinzu. Wenn Sie die Signatur der Index Methode geändert haben, um zu testen, wie der routengebundene ID-Parameter übergeben wird, ändern Sie ihn zurück, sodass Ihre Index Methode einen Zeichenfolgenparameter mit dem Namen akzeptiert 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); 
}

Öffnen Sie die Datei Views\Movies\Index.cshtml , und fügen Sie direkt danach @Html.ActionLink("Create New", "Create")das unten hervorgehobene Formularmarkup hinzu:

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

Das Html.BeginForm Hilfsprogramm erstellt ein öffnendes <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.

Visual Studio 2013 hat eine schöne Verbesserung beim Anzeigen und Bearbeiten von Ansichtsdateien. Wenn Sie die Anwendung mit geöffneter Ansichtsdatei ausführen, ruft Visual Studio 2013 die richtige Controlleraktionsmethode auf, um die Ansicht anzuzeigen.

Screenshot: Indexpunkt c s h t m l Registerkarte und Projektmappen-Explorer geöffnet. In Projektmappen-Explorer ist der Unterordner Filme geöffnet, und Indexpunkt c s h t m l ist ausgewählt.

Wenn die Indexansicht in Visual Studio geöffnet ist (wie in der Abbildung oben dargestellt), tippen Sie auf Ctr F5 oder F5, um die Anwendung auszuführen, und versuchen Sie dann, nach einem Film zu suchen.

Screenshot: Seite

Es gibt keine HttpPost Überladung der Index Methode. Sie benötigen es nicht, da die Methode den Status der Anwendung nicht ändert, nur Daten filtert.

Sie können die folgende HttpPost Index-Methode hinzufügen. In diesem Fall würde der Aktionsaufrufer mit der HttpPost Index -Methode übereinstimmen, und die HttpPost Index -Methode würde wie in der folgenden Abbildung dargestellt ausgeführt.

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

SearchPostGhost

Doch selbst wenn Sie diese HttpPost-Version der Index-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/Index) identisch ist. Die URL selbst enthält keine Suchinformationen. Derzeit werden die Suchzeichenfolgeninformationen als Formularfeldwert an den Server gesendet. Dies bedeutet, dass Sie diese Suchinformationen nicht erfassen können, um in einer URL ein Lesezeichen zu speichern oder an Freunde zu senden.

Die Lösung besteht darin, eine Überladung von BeginForm zu verwenden, die angibt, dass die POST-Anforderung die Suchinformationen zur URL hinzufügen und an die HttpGet Version der Index Methode weitergeleitet werden soll. Ersetzen Sie die vorhandene methode ohne parameter durch BeginForm das folgende Markup:

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

BeginFormPost_SM

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

IndexWithGetURL

Hinzufügen der Suche nach Genre

Wenn Sie die HttpPost Version der Index 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 Index-Methode durch folgenden Code:

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

Diese Version der Index -Methode verwendet einen zusätzlichen Parameter, nämlich movieGenre. Mit 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 der Liste alle unterschiedlichen Genres hinzuzufügen. (Ohne den Distinct Modifizierer würden doppelte Genres hinzugefügt – z. B. Komödien würden in unserem Beispiel zweimal hinzugefügt). Der Code speichert dann die Liste der Genres im ViewBag.MovieGenre -Objekt. Das Speichern von Kategoriedaten (z. B. Filmgenres) als SelectList-Objekt in einem ViewBagund dann der Zugriff auf die Kategoriedaten in einem Dropdownlistenfeld ist ein typischer Ansatz für MVC-Anwendungen.

Der folgende Code zeigt, wie Der movieGenre Parameter überprüft wird. Wenn es 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))
{
    movies = movies.Where(x => x.Genre == movieGenre);
}

Wie bereits erwähnt, wird die Abfrage erst in der Datenbank ausgeführt, wenn die Filmliste durchlaufen wurde (was in der Ansicht geschieht, nachdem die Index Aktionsmethode zurückgegeben wurde).

Hinzufügen von Markup zur Indexansicht zur Unterstützung der Suche nach Genre

Fügen Sie der Datei Views\Movies\Index.cshtml direkt vor dem TextBox Hilfsprogramm ein Html.DropDownList Hilfsprogramm hinzu. Das abgeschlossene Markup ist unten dargestellt:

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

Im folgenden Code wird Folgendes ausgeführt:

@Html.DropDownList("movieGenre", "All")

Der Parameter "MovieGenre" stellt den Schlüssel für das DropDownList Hilfsprogramm bereit, um eine IEnumerable<SelectListItem> in zu ViewBagfinden. Der ViewBag wurde in der Aktionsmethode aufgefüllt:

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

Der Parameter "All" stellt eine Optionsbezeichnung bereit. Wenn Sie diese Option in Ihrem Browser überprüfen, sehen Sie, dass das Attribut "value" leer ist. Da unser Controller nur filtert if , dass die Zeichenfolge nicht null oder leer ist, zeigt das Übermitteln eines leeren Werts für movieGenre alle Genres an.

Sie können auch eine Option festlegen, die standardmäßig ausgewählt werden soll. Wenn Sie "Comedy" als Standardoption verwenden möchten, würden Sie den Code im Controller wie folgt ändern:

ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");

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

Screenshot: Seite

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