Partager via


Rechercher

Notes

Une version mise à jour de ce didacticiel est disponible ici à l’aide de la dernière version de Visual Studio. Le nouveau tutoriel utilise ASP.NET Core MVC, qui fournit de nombreuses améliorations par rapport à ce tutoriel.

Ce didacticiel décrit ASP.NET Core MVC avec des contrôleurs et des vues. Razor Pages est une nouvelle alternative dans ASP.NET Core, un modèle de programmation basé sur des pages qui rend la création d’interface utilisateur web plus facile et plus productive. Nous vous recommandons de suivre le didacticiel sur les pages Razor avant la version MVC. Le didacticiel sur les pages Razor :

  • est plus facile à suivre ;
  • couvre davantage de fonctionnalités ;
  • Est l’approche préférée pour le développement de nouvelles applications.

Ajout d’une méthode de recherche et d’une vue de recherche

Dans cette section, vous allez ajouter la fonctionnalité de recherche à la Index méthode d’action qui vous permet de rechercher des films par genre ou par nom.

Prérequis

Pour correspondre aux captures d’écran de cette section, vous devez exécuter l’application (F5) et ajouter les films suivants à la base de données.

Titre Date de sortie Genre Prix
Ghostbusters 6/8/1984 Comédie 6,99
Ghostbusters II 6/16/1989 Comédie 6,99
Planète des singes 3/27/1986 Action 5,99

Mise à jour du formulaire d’index

Commencez par mettre à jour la Index méthode d’action vers la classe existante MoviesController . Voici le code :

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

La première ligne de la Index méthode crée la requête LINQ suivante pour sélectionner les films :

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

La requête est définie à ce stade, mais n’a pas encore été exécutée sur la base de données.

Si le searchString paramètre contient une chaîne, la requête movies est modifiée pour filtrer la valeur de la chaîne de recherche, à l’aide du code suivant :

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

Le code s => s.Title ci-dessus est une expression lambda. Les lambdas sont utilisés dans les requêtes LINQ basées sur une méthode en tant qu’arguments pour les méthodes d’opérateur de requête standard telles que la méthode Where utilisée dans le code ci-dessus. Les requêtes LINQ ne sont pas exécutées lorsqu’elles sont définies ou lorsqu’elles sont modifiées en appelant une méthode telle que Where ou OrderBy. Au lieu de cela, l’exécution de la requête est différée, ce qui signifie que l’évaluation d’une expression est retardée jusqu’à ce que sa valeur réalisée soit réellement itérée ou que la ToList méthode soit appelée. Dans l’exemple Search , la requête est exécutée dans la vue Index.cshtml . Pour plus d’informations sur l’exécution différée des requêtes, consultez Exécution de requête.

Notes

La méthode Contains est exécutée sur la base de données, et non sur le code c# ci-dessus. Sur la base de données, contient des mappages à SQL LIKE, qui ne respecte pas la casse.

Vous pouvez maintenant mettre à jour la Index vue qui affichera le formulaire pour l’utilisateur.

Exécutez l’application et accédez à /Movies/Index. Ajoutez une chaîne de requête comme ?searchString=ghost à l’URL. Les films filtrés sont affichés.

SearchQryStr

Si vous modifiez la signature de la Index méthode pour avoir un paramètre nommé id, le id paramètre correspondra à l’espace {id} réservé pour les itinéraires par défaut définis dans le fichier App_Start\RouteConfig.cs .

{controller}/{action}/{id}

La méthode d’origine Index ressemble à ceci :

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

La méthode modifiée Index se présente comme suit :

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

Vous pouvez maintenant passer le titre de la recherche en tant que données de routage (un segment de l’URL) et non pas en tant que valeur de chaîne de requête.

Capture d’écran montrant la page M V C Movie Index. Deux-points de l’hôte local 1 2 3 4 barre oblique Films la barre oblique de la barre oblique de l’index d’avant est dans le champ U R L et cerclée en rouge.

Cependant, vous ne pouvez pas attendre des utilisateurs qu’ils modifient l’URL à chaque fois qu’ils veulent rechercher un film. Vous allez donc maintenant ajouter une interface utilisateur pour les aider à filtrer les films. Si vous avez modifié la signature de la Index méthode pour tester la réussite du paramètre d’ID lié à l’itinéraire, modifiez-la afin que votre Index méthode prenne un paramètre de chaîne nommé 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); 
}

Ouvrez le fichier Views\Movies\Index.cshtml et, juste après @Html.ActionLink("Create New", "Create"), ajoutez le balisage de formulaire mis en évidence ci-dessous :

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

L’assistance Html.BeginForm crée une balise d’ouverture <form> . L’assistance Html.BeginForm fait publier le formulaire sur lui-même lorsque l’utilisateur envoie le formulaire en cliquant sur le bouton Filtrer .

Visual Studio 2013 présente une belle amélioration lors de l’affichage et de la modification des fichiers d’affichage. Lorsque vous exécutez l’application avec un fichier d’affichage ouvert, Visual Studio 2013 appelle la méthode d’action du contrôleur appropriée pour afficher la vue.

Capture d’écran montrant l’onglet Index point c s h t m l et Explorateur de solutions ouvert. Dans Explorateur de solutions, le sous-dossier Films est ouvert et Index dot c s h t m l est sélectionné.

Avec la vue Index ouverte dans Visual Studio (comme illustré dans l’image ci-dessus), appuyez sur Ctr F5 ou F5 pour exécuter l’application, puis essayez de rechercher un film.

Capture d’écran montrant la page Index avec un titre entré dans le champ Titre.

Il n’y a pas HttpPost de surcharge de la Index méthode. Vous n’en avez pas besoin, car la méthode ne modifie pas l’état de l’application, mais simplement le filtrage des données.

Vous pourriez ajouter la méthode HttpPost Index suivante. Dans ce cas, l’appelant d’action correspondrait à la HttpPost Index méthode et la HttpPost Index méthode s’exécuterait comme indiqué dans l’image ci-dessous.

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

SearchPostGhost

Cependant, même si vous ajoutez cette version HttpPost de la méthode Index, il existe une limitation dans la façon dont tout ceci a été implémenté. Imaginez que vous voulez insérer un signet pour une recherche spécifique, ou que vous voulez envoyer un lien à vos amis sur lequel ils peuvent cliquer pour afficher la même liste filtrée de films. Notez que l’URL de la requête HTTP POST est identique à l’URL de la requête GET (localhost:xxxxx/Movies/Index) : il n’y a aucune information de recherche dans l’URL elle-même. À l’heure actuelle, les informations de chaîne de recherche sont envoyées au serveur sous la forme d’une valeur de champ de formulaire. Cela signifie que vous ne pouvez pas capturer ces informations de recherche à signet ou à envoyer à des amis dans une URL.

La solution consiste à utiliser une surcharge de BeginForm qui spécifie que la requête POST doit ajouter les informations de recherche à l’URL et qu’elle doit être acheminée vers la HttpGet version de la Index méthode. Remplacez la méthode sans BeginForm paramètre existante par le balisage suivant :

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

BeginFormPost_SM

À présent, lorsque vous envoyez une recherche, l’URL contient une chaîne de requête de recherche. La recherche accède également à la méthode d’action HttpGet Index, même si vous avez une méthode HttpPost Index.

IndexWithGetURL

Ajout de la recherche par genre

Si vous avez ajouté la HttpPost version de la méthode, supprimez-la Index maintenant.

Ensuite, vous allez ajouter une fonctionnalité pour permettre aux utilisateurs de rechercher des films par genre. Remplacez la méthode Index par le code suivant :

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

Cette version de la Index méthode prend un paramètre supplémentaire, à savoir movieGenre. Les premières lignes de code créent un List objet pour contenir les genres de films de la base de données.

Le code suivant est une requête LINQ qui récupère tous les genres dans la base de données.

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

Le code utilise la AddRange méthode de la collection générique List pour ajouter tous les genres distincts à la liste. (Sans le Distinct modificateur, des genres en double seraient ajoutés ( par exemple, la comédie serait ajoutée deux fois dans notre exemple). Le code stocke ensuite la liste des genres dans l’objet ViewBag.MovieGenre . Le stockage de données de catégorie (tels qu’un genre vidéo) en tant qu’objet SelectList dans un ViewBag, puis l’accès aux données de catégorie dans une zone de liste déroulante est une approche classique pour les applications MVC.

Le code suivant montre comment case activée le movieGenre paramètre. S’il n’est pas vide, le code contraint davantage la requête movies à limiter les films sélectionnés au genre spécifié.

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

Comme indiqué précédemment, la requête n’est pas exécutée sur la base de données tant que la liste de films n’est pas itérée (ce qui se produit dans la vue, une fois que la Index méthode d’action est retournée).

Ajout de balisage à la vue Index pour prendre en charge la recherche par genre

Ajoutez un Html.DropDownList helper au fichier Views\Movies\Index.cshtml , juste avant l’assistance TextBox . Le balisage terminé est illustré ci-dessous :

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

Dans le code suivant :

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

Le paramètre « MovieGenre » fournit la clé pour que l’assistance DropDownList trouve un IEnumerable<SelectListItem> dans le ViewBag. a ViewBag été renseigné dans la méthode d’action :

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

Le paramètre « All » fournit une étiquette d’option. Si vous inspectez ce choix dans votre navigateur, vous verrez que son attribut « value » est vide. Étant donné que notre contrôleur filtre if uniquement la chaîne n’est pas null ou vide, l’envoi d’une valeur vide pour movieGenre affiche tous les genres.

Vous pouvez également définir une option à sélectionner par défaut. Si vous vouliez « Comedy » comme option par défaut, vous devez modifier le code dans le contrôleur comme suit :

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

Exécutez l’application et accédez à /Movies/Index. Essayez une recherche par genre, par nom de film et par deux critères.

Capture d’écran montrant la page Index. Un type de genre est sélectionné.

Dans cette section, vous avez créé une méthode et une vue d’action de recherche qui permettent aux utilisateurs de rechercher par titre et par genre de film. Dans la section suivante, vous allez voir comment ajouter une propriété au Movie modèle et comment ajouter un initialiseur qui créera automatiquement une base de données de test.