然而,尽管添加了 [HttpPost] 版的 Index 方法,在实现的时候仍然存在一些局限性。设想你想将一个比较详细的查询添加书签,或者你想将查询结果以链接形式发送给朋友以便于你的朋友可以看到同样的过滤结果的电影,注意观察 HTTP POST 请求的时候,URL 是没有改变的(仍然是 localhost:xxxxx/Movies/Index),这个地址本身不包含查询信息。现在,查询信息是作为表单数据发送到服务器的,你可以通过 F12 开发者工具或者优秀的抓包工具 Fiddler tool。启动F12 开发者工具。
选择 :xxx/Movies HTTP POST 200 行点击 Body > Request Body。
你可以在请求正文中看到查询参数和上一个教程中提到的XSRF令牌。Form Tag Helper生成XSRF 反伪造令牌。我们没有修改数据,所以无需在控制器方法中验证令牌。
因为查询参数在请求正文中而不是 Url 里,所以你在书签里面无法保存查询参数并共享给他人,为了解决这个问题,我们必须把请求指定为 HTTP GET。注意智能感知将帮我们更新标签。
请注意, <form> 标签中的专有标记。这种专有标记表示的标签是由Tag Helpers 支持的。
当你提交检索的时候,URL 包含查询条件,如果存在 HttpPost Index 方法,查询会跳转到 HttpGet Index 方法。
添加按照 Genre 查询在 Models 目录添加下面的 MovieGenreViewModel 类:
using Microsoft.AspNetCore.Mvc.Rendering; using System.Collections.Generic; namespace MvcMovie.Models { public class MovieGenreViewModel { public List<Movie> movies; public SelectList genres; public string movieGenre { get; set; } } }move-genre 视图模型包含:
用下面的代码替换 Index 方法:
public async Task<IActionResult> Index(string movieGenre, string searchString) { 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(); movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync()); movieGenreVM.movies = await movies.ToListAsync(); return View(movieGenreVM); }下面代码是通过 LINQ 语句从数据库中检索所有 genre 数据。
IQueryable<string> genreQuery = from m in _context.Movie orderby m.Genre select m.Genre;SelectList 的 genres 通过 Distinct 方法投影查询创建(我们不想选择列表中出现重复的数据)。
movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync()); 在 Index 视图中添加通过 genre 检索 <!--手工高亮--> @model MovieGenreViewModel @{ ViewData["Title"] = "Index"; } <h2>Index</h2> <p> <a asp-action="Create">Create New</a> </p> <form asp-controller="Movies" asp-action="Index" method="get"> <p> <select asp-for="movieGenre" asp-items="Model.genres"> <!--手工高亮--> <option value="">All</option> <!--手工高亮--> </select> <!--手工高亮--> Title: <input type="text" name="SearchString"> <input type="submit" value="Filter" /> </p> </form> <table class="table"> <tr> <th> @Html.DisplayNameFor( model => model.movies[0].Genre ) <!--手工高亮--> </th> <th> @Html.DisplayNameFor( model => model.movies[0].Price ) </th> <th> @Html.DisplayNameFor( model => model.movies[0].ReleaseDate ) </th> <th> @Html.DisplayNameFor( model => model.movies[0].Title ) </th> <th></th> </tr> <tbody> @foreach( var item in Model.movies ) //手工高亮 { <tr> <td> @Html.DisplayFor( modelItem => item.Genre ) </td> <td> @Html.DisplayFor( modelItem => item.Price ) </td> <td> @Html.DisplayFor( modelItem => item.ReleaseDate ) </td> <td> @Html.DisplayFor( modelItem => item.Title ) </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> </table>测试程序并分别通过 genre 或者 电影标题以及两个条件同时进行检索
返回目录
posted @