Adding Search
https://docs.asp.net/en/latest/tutorials/first-mvc-app/search.html
In this section you’ll add search capability to the Index
action method that lets you search movies by genre or name.
Update the Index
action method to enable search:
public async Task<IActionResult> Index(string searchString)
{
var movies = _context.Movie.Select(x => x); if (string.IsNullOrEmpty(searchString) == false)
{
movies = movies.Where(x => x.Title.Contains(searchString));
} return View(await movies.ToListAsync());
}
上面第一行代码,还可以改为
var movies = from m in _context.Movie
select m;
The first line of the Index
action method creates a LINQ query to select the movies:
The query is only defined at this point, it has not been run against the database.
If the searchString
parameter contains a string, the movies query is modified to filter on the value of the search string, using the following code:
if (string.IsNullOrEmpty(searchString) == false)
{
movies = movies.Where(x => x.Title.Contains(searchString));
}
The x => x.Title.Contains()
code above is a Lambda Expression.
Lambdas are used in method-based LINQ queries as arguments to standard query operator methods such as the Where method or Contains
used in the code above.
LINQ queries are not executed when they are defined or when they are modified by calling a method such as Where
, Contains
or OrderBy
.
Instead, query execution is deferred, which means that the evaluation of an expression is delayed until its realized value is actually iterated over or the ToListAsync
method is called.
For more information about deferred query execution, see Query Execution. //延迟加载
Note:
The Contains method is run on the database, not the c# code above.
On the database, Containsmaps to SQL LIKE, which is case insensitive. //不区分大小写
Navigate to /Movies/Index
. Append a query string such as ?searchString=ghost
to the URL. The filtered movies are displayed.
If you change the signature of the Index
method to have a parameter named id
, the id
parameter will match the optional {id}
placeholder for the default routes set in Startup.cs.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
You can quickly rename the searchString
parameter to id
with the rename command.
Right click on searchString
> Rename.
Change the parameter to id
and all occurrences of searchString
change to id
.
You can now pass the search title as route data (a URL segment) instead of as a query string value.
However, you can’t expect users to modify the URL every time they want to search for a movie.
So now you’ll add UI to help them filter movies.
If you changed the signature of the Index
method to test how to pass the route-bound ID
parameter, change it back so that it takes a parameter named searchString
:
添加一个Filter进行过滤
Open the Views/Movies/Index.cshtml file, and add the <form>
markup highlighted below:
@{
ViewData["Title"] = "Index";
} <h2>Index</h2> <p>
<a asp-action="Create">Create New</a>
</p> <form asp-controller="Movies" asp-action="Index">
<p>
Title: <input type="text" name="SearchString">
<input type="submit" value="Filter" />
</p>
</form> <table class="table">
The HTML <form>
tag uses the Form Tag Helper, so when you submit the form, the filter string is posted to the Index
action of the movies controller.
Save your changes and then test the filter.
There’s no [HttpPost]
overload of the Index
method as you might expect.
You don’t need it, because the method isn’t changing the state of the app, just filtering data.
You could add the following [HttpPost] Index
method.
[HttpPost]
public string Index(string searchString, bool notUsed)
{
return "From [HttpPost]Index: filter on " + searchString;
}
The notUsed
parameter is used to create an overload for the Index
method.
We’ll talk about that later in the tutorial.
If you add this method, the action invoker would match the [HttpPost] Index
method, and the[HttpPost] Index
method would run as shown in the image below.
[HttpPost]
public string Index(string searchString, bool notUsed)
{
return "From [HttpPost]Index: filter on " + searchString;
}
这个方法添加之后,保存。然后重新刷新界面,再用ghost进行filter过滤,会出现下图
However, even if you add this [HttpPost]
version of the Index
method, there’s a limitation in how this has all been implemented.
Imagine that you want to bookmark a particular search or you want to send a link to friends that they can click in order to see the same filtered list of movies.
Notice that the URL for the HTTP POST request is the same as the URL for the GET request (localhost:xxxxx/Movies/Index) – there’s no search information in the URL.
The search string information is sent to the server as a form field value.
You can verify that with the F12 Developer tools or the excellent Fiddler tool.
Start the F12 tool:
You can see the search parameter and XSRF token in the request body.
Note, as mentioned in the previous tutorial, the Form Tag Helper generates an XSRF anti-forgery token.
We’re not modifying data, so we don’t need to validate the token in the controller method.
Because the search parameter is in the request body and not the URL, you can’t capture that search information to bookmark or share with others.
We’ll fix this by specifying the request should be HTTP GET
. Notice how intelliSense helps us update the markup.
<form asp-controller="Movies" asp-action="Index" method="get">
<p>
Title: <input type="text" name="SearchString">
<input type="submit" value="Filter"/>
</p>
</form>
Notice the distinctive font in the <form>
tag. That distinctive font indicates the tag is supported byTag Helpers.
Now when you submit a search, the URL contains the search query string.
Searching will also go to the HttpGet Index
action method, even if you have a HttpPost Index
method.
Adding Search by Genre
Add the following MovieGenreViewModel
class to the Models folder:
public class MovieGenreViewModel
{
public List<Movie> Movies; public SelectList Genres; public string MovieGenre { get; set; }
}
The move-genre view model will contain:
- a list of movies
- a SelectList containing the list of genres. This will allow the user to select a genre from the list.
movieGenre
, which contains the selected genre
Replace the Index
method with the following code:
public async Task<IActionResult> Index(string movieGenre,string searchString)
{
var movies = _context.Movie.Select(x => x); var genres = movies.Select(x => x.Genre).Distinct(); if (string.IsNullOrEmpty(searchString) == false)
{
movies = movies.Where(x => x.Title.Contains(searchString));
} if (string.IsNullOrEmpty(movieGenre)==false)
{
movies = movies.Where(x => x.Genre == movieGenre);
} MovieGenreViewModel movieGenreViewModel = new MovieGenreViewModel();
movieGenreViewModel.Genres = new SelectList(await genres.ToListAsync());
movieGenreViewModel.Movies = await movies.ToListAsync(); return View(movieGenreViewModel);
}
Adding search by genre to the Index view
@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">
<thead>
<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>
</thead>
<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>
Test the app by searching by genre, by movie title, and by both.
Adding Search的更多相关文章
- 011.Adding Search to an ASP.NET Core MVC app --【给程序添加搜索功能】
Adding Search to an ASP.NET Core MVC app 给程序添加搜索功能 2017-3-7 7 分钟阅读时长 作者 本文内容 1.Adding Search by genr ...
- ASP.NET Core 中文文档 第二章 指南(4.7)添加搜索
原文:Adding Search 作者:Rick Anderson 翻译:魏美娟(初见) 校对:谢炀(Kiler) .孟帅洋(书缘).张仁建(第二年.夏) 在本节中,你可以为 Index 方法添加查询 ...
- IOS 开发教程
http://www.raywenderlich.com/category/ios http://www.raywenderlich.com/50310/storyboards-tutorial-in ...
- ASP.NEt MVC5--创建下拉列表
Adding Search by Genre If you added the HttpPost version of the Index method, delete it now. Next, ...
- Using ASP.Net WebAPI with Web Forms
Asp.Net WebAPI is a framework for building RESTful HTTP services which can be used across a wide ran ...
- 004.Create a web app with ASP.NET Core MVC using Visual Studio on Windows --【在 windows上用VS创建mvc web app】
Create a web app with ASP.NET Core MVC using Visual Studio on Windows 在 windows上用VS创建mvc web app 201 ...
- Android Training
Building Apps with Content Sharing Simple Data --> Intent && ActionProvider 介绍如何让应用程序共享简单 ...
- CDN:分类
ylbtech-CDN:分类 1.返回顶部 1. bootstrap Bootstrap 是全球最受欢迎的前端组件库,用于开发响应式布局.移动设备优先的 WEB 项目. 2. feather-icon ...
- [LeetCode] Binary Search Tree Iterator 二叉搜索树迭代器
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...
随机推荐
- ionic + cordova开发APP遇到的一些坑
ionic1时期接触了这套体系,做了一个APP之后就放置了,最近又要开发一个APP,但时间不足以让我重头了解typescripts,于是又把之前做过的东西翻了出来,一边做一边掉坑里,爬上来再掉坑里,所 ...
- .Net并行计算支持嵌套事务的方法
问题背景 一年前,我们开始利用.Net 4.0的TPL(Task Parallel Library)并行计算技术对复杂计算的功能节点进行性能优化,这些复杂计算往往会包含大量对数据库的操作.在应用TPL ...
- 黑客常用dos命令
http://blog.csdn.net/CSDN___LYY/article/details/77802438
- ubuntu16.04安装KDE
由于对KDE界面情有独钟,升级到ubuntu之后,第一件事就是安装kde桌面 命令: add-apt-repository ppa:kubuntu-ppa/backports apt-get upda ...
- 安卓桌布显示的dip和px
安卓程序设计界面显示设置图像大小,在layout.xml里面有dip和px选项,dip为 什么 暂时还不知道,或许是设计桌布的设定像素比率,px为像素值: 比如我的手机是 Lenovo K920,屏幕 ...
- JSP_内置对象_response
response对象: response对象包含了相应客户请求的有关信息,但在JSP中很少直接用到它,它是HttpServletResponse类的实例.response对象具有页面作用域,即访问一个 ...
- Linux 之根目录介绍
1. /bin binary二进制 存放系统许多可执行程序文件 执行的相关指令,例如ls pwd whoami,后台的支持文件目录 2. /sbin super binary超级的二进制 存放系统许多 ...
- Robot Framework(八) 资源和变量文件
2.7资源和变量文件 测试用例文件和测试套件初始化文件中的用户关键字和变量只能在创建它们的文件中使用,但资源文件提供了共享它们的机制.由于资源文件结构非常接近测试用例文件,因此很容易创建它们. 变量文 ...
- tomcat多实例的部署
解压部署tomcat程序创建2个实例的工作目录mkdir -p /usr/local/tomcat8_instance/tomcat1mkdir -p /usr/local/tomcat8_insta ...
- vue-路由使用
路由安装 终端下载路由插件 npm install vue-router --save-dev 配置 在main.js中引入插件 //Router 为自定义名 vue-router 为插件的名字 im ...