Freigeben über


Suchen

Hinweis

Eine aktualisierte Version dieses Lernprogramms ist hier mit der neuesten Version von Visual Studio verfügbar. Das neue Lernprogramm verwendet ASP.NET Core MVC, das viele Verbesserungen in diesem Lernprogramm bietet.

In diesem Lernprogramm lernen Sie ASP.NET Core MVC mit Controllern und Ansichten. Razor Pages ist eine neue Alternative in ASP.NET Core, einem seitenbasierten Programmiermodell, das das Erstellen von Web-UI erleichtert und produktiver macht. Wir empfehlen Ihnen, das Lernprogramm "Razor Pages " vor der MVC-Version zu testen. Das Razor Pages-Tutorial:

  • Es ist einfacher zu folgen.
  • Umfasst mehr Funktionen.
  • Ist der bevorzugte Ansatz für die entwicklung neuer Apps.

Hinzufügen einer Suchmethode und Suchansicht

In diesem Abschnitt fügen Sie der Aktionsmethode Index eine Suchfunktion hinzu, mit der Sie Filme nach Genre oder Name 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.

Title Erscheinungsdatum Genre Preis
Ghostbusters 6/8/1984 Komödie 6,99
Ghostbusters II 6/16/1989 Komödie 6,99
Planet der Apen 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 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 bei ihrer Definition oder wenn sie durch Aufrufen einer Methode wie Where oder OrderBy geändert werden. 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. Search Im Beispiel wird die Abfrage in der Index.cshtml-Ansicht 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 obigen C#-Code ausgeführt. Enthält in der Datenbank Zuordnungen zu SQL LIKE, bei denen die Groß-/Kleinschreibung nicht beachtet wird.

Jetzt können Sie die Index Ansicht aktualisieren, die das Formular für den Benutzer anzeigt.

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 so ändern, dass ein Parameter benannt idist, entspricht der id Parameter dem {id} Platzhalter für die in der Datei App_Start\RouteConfig.cs festgelegten Standardrouten.

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

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 Index-Methode geändert haben, um zu testen, wie der routen-gebundene ID-Parameter übergeben wird, stellen Sie die ursprüngliche Signatur wieder her, sodass die Index-Methode einen Zeichenfolgenparameter namens searchString annimmt.

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 gesendet wird, wenn der Benutzer das Formular sendet, indem er auf die Schaltfläche 'Filter' klickt.

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

Screenshot, der die Registerkarte

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

Es gibt keine HttpPost Überladung der Index Methode. Es ist nicht nötig, weil die Methode den Zustand der Anwendung nicht ändert, sondern nur Daten filtert.

Sie können die folgende HttpPost Index-Methode hinzufügen. In diesem Fall stimmt der Aktionsaufrufer mit der HttpPost Index Methode überein, und die HttpPost Index Methode würde wie in der abbildung unten 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 – 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 Index Methode weitergeleitet werden soll. Ersetzen Sie die vorhandene parameterlose BeginForm Methode durch das folgende Markup:

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

BeginFormPost_SM

Wenn Sie nun eine Suche übermitteln, enthält die URL eine Suchabfragezeichenfolge. Die Suche gelangt auch zur Aktionsmethode HttpGet Index, selbst 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 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.MovieGenre Objekt. Das Speichern von Kategoriedaten (z. B. Filmgenres) als SelectList-Objekt in einem ViewBag, und 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 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))
{
    movies = movies.Where(x => x.Genre == movieGenre);
}

Wie bereits erwähnt, wird die Abfrage nicht in der Datenbank ausgeführt, bis die Filmliste durchlaufen wird (was in der Ansicht geschieht, nachdem die Index Aktionsmethode zurückkehrt).

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

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

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

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

Der Parameter "MovieGenre" liefert den Schlüssel für die DropDownList Hilfsfunktion, um ein IEnumerable<SelectListItem> im ViewBag zu finden. Das ViewBag wurde in der Aktionsmethode befü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 Auswahl in Ihrem Browser überprüfen, sehen Sie, dass das Attribut "value" leer ist. Wenn unser Controller nur if filtert und die Zeichenfolge nicht null leer ist, zeigt das Übermitteln eines leeren Wertes 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 wünschen, ändern Sie den Code im Controller wie folgt:

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

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

Screenshot der 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 Movie Modell eine Eigenschaft hinzufügen und einen Initialisierer hinzufügen, der automatisch eine Testdatenbank erstellt.