.NET Core - MVC 应用中添加搜索

  Controllers/MoviesControllers.cs中的Index方法更新代码:

    public async Task<IActionResult> Index(string searchString)

    {
      var movies = from m in _context.Movie
            select m;

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

      return View(await movies.ToListAsync());
    }

    方法第一行创建了LINQ查询用于选择电影。

    如果searchString参数包含一个字符串,电影查询会被修改为根据搜索字符串的值进行筛选:

      例 : if (!String.IsNullOrEmpty(searchString))

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

    导航到Movies/Index

    将查询字符串追加到URL(例:?searchString=Ghost),筛选的电影将显示出来。

  如果将Index方法的签名更改为具有名为id的参数,id参数将匹配Program.cs中设置的默认路由的可选{id}占位符。

    例 : app.MapControllerRoute(

        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    将参数更改为id,并将出现的所有searchString更改为id。

    更改的代码部分(【】括号中为更改前):

      ① public async Task<IActionResult> Index(string id)

          更改前:

       【

        public async Task<IActionResult> Index(string searchString)

       】

      ② if (!String.IsNullOrEmpty(id))

        {

          movies = movies.Where(s => s.Title!.Contains(id));

        }
          更改前:

       【

        if (!String.IsNullOrEmpty(searchString))

        {

          movies = movies.Where(s => s.Title!.Contains(searchString));

        }

       】

      更改后,可将搜索标题座位路由数据(URL段)而非查询字符串值进行传递。

        例 : https://localhost:5001/Movies/Index/ghost

      原则上不能每次搜索电影时都修改URL。因此,需要添加UI元素来筛选电影。

      上述修改内容,恢复到原样searchString参数。

  对Views/Movies/Index.cshtml文件,添加<form>标记,添加内容,如下:

    <form asp-controller="Movies" asp-action="Index" method="get">

      <p> Title: <input type="text" name="SearchString" />

        <input type="submit" value="Filter" />

      </p>

    </form>

  访问地址:https://localhost:5001/Movies 进行测试.

  

  按类别搜索:

    Models添加类 MovieGenreViewModel

    例 : using Microsoft.AspNetCore.Mvc.Rendering;

      using System.Collections.Generic;

      namespace MvcMovie.Models
      {
        public class MovieGenreViewModel
        {
          public List<Movie>? Movies { get; set; }
          public SelectList? Genres { get; set; }
          public string? MovieGenre { get; set; }
          public string? SearchString { get; set; }
        }
      }

      SelectList? Genres : 类别列表集合

      string? MovieGenre : 所选类别

      string? SearchString : 用户在搜索文本框中输入的文本

    MoviesController.cs中的Index方法替换为:

      // GET: Movies

      public async Task<IActionResult> Index(string movieGenre, string searchString)
      {
        // Use LINQ to get list of genres.
        IQueryable<string> genreQuery = from m in _context.Movie
                        orderby m.Genre
                        select m.Genre;
        var movies = from m in _context.Movie
              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);
        }

        var movieGenreVM = new MovieGenreViewModel
        {
          Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
          Movies = await movies.ToListAsync()
        };

        return View(movieGenreVM);
      }

    Views/Movies/ 中的 Index.cshtml更新如下:

       第一行 :@model MvcMovie.Models.MovieGenreViewModel

       <form>内 : <select asp-for="MovieGenre" asp-items="Model.Genres">

               <option value="">All</option>

             </select>

             Title: <input type="text" asp-for="SearchString" />

             <input type="submit" value="Filter" />

       <table>内 : <thead>

              <tr>

                <th>@Html.DisplayNameFor(model => model.Movies[0].Title)</th>

                <th> @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate) </th>

                <th> @Html.DisplayNameFor(model => model.Movies[0].Genre) </th>

                <th> @Html.DisplayNameFor(model => model.Movies[0].Price) </th>

                <th></th>

              </tr>

            </thead>

            <tbody> @foreach (var item in Model.Movies) {

              <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> <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |

                  <a asp-action="Details" asp-route-id="@item.Id">Details</a> |

                  <a asp-action="Delete" asp-route-id="@item.Id">Delete</a> </td>

              </tr> }

            </tbody>

     DisplayNameFor HTML 帮助程序检查 Lambda 表达式中引用的 Title 属性来确定显示名称。

       由于只检查但未计算 Lambda 表达式,因此当 modelmodel.Movies[0] 或 model.Movies 为 null 或空时,你不会收到访问冲突。

       对 Lambda 表达式求值时(例如,@Html.DisplayFor(modelItem => item.Title)),将求得该模型的属性值。

       访问 : 测试

posted @ 2022-07-04 16:47  大师兄被妖怪抓走了  阅读(96)  评论(0编辑  收藏  举报