011.Adding Search to an ASP.NET Core MVC app --【給程式添加搜索功能】

来源:http://www.cnblogs.com/Meng-NET/archive/2017/08/21/7405047.html
-Advertisement-
Play Games

Adding Search to an ASP.NET Core MVC app 給程式添加搜索功能 2017-3-7 7 分鐘閱讀時長 作者 本文內容 1.Adding Search by genre 根據音樂流派添加搜索 2.Adding search by genre to the Index ...


Adding Search to an ASP.NET Core MVC app

給程式添加搜索功能

2017-3-7 7 分鐘閱讀時長 作者 

本文內容

1.Adding Search by genre

根據音樂流派添加搜索

2.Adding search by genre to the Index view

在 Index 視圖添加音樂流派搜索功能

By Rick Anderson

In this section you add search capability to the Index action method that lets you search movies by genre or name.

在本節我們將給 Index 方法添加搜索功能,可以搜索音樂流派或音樂的名字。

Update the Index method with the following code:

用下麵的代碼更新 Index 方法:

 1 public async Task<IActionResult> Index(string searchString)
 2 
 3 {
 4 
 5     var movies = from m in _context.Movie
 6 
 7                  select m;
 8 
 9  
10 
11     if (!String.IsNullOrEmpty(searchString))
12 
13     {
14 
15         movies = movies.Where(s => s.Title.Contains(searchString));
16 
17     }
18 
19  
20 
21     return View(await movies.ToListAsync());
22 
23 }
C# code

The first line of the Index action method creates a LINQ query to select the movies:

Index 方法的第一行寫了一個 LINQ 查詢表達式,以查詢出movie數據:

1 var movies = from m in _context.Movie
2 
3              select m;
C# code

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:

searchString 參數包含了一個字元串,movie查詢會去根據這個搜索字元串過濾查詢數據:

1 if (!String.IsNullOrEmpty(id))
2 
3 {
4 
5     movies = movies.Where(s => s.Title.Contains(id));
6 
7 }
C# code

The s => s.Title.Contains() code above is a Lambda Expression.

上面的 s => s.Title.Contains() 是 Lambda 表達式。

Lambdas are used in method-based LINQqueries as arguments to standard query operator methods such as the Where method or Contains (used in the code above).

Lambda 表達式被用於基於函數為參數的標準操作函數,如: Where 方法或上面的 Contains 方法。

LINQ queries are not executed when they are defined or when they are modified by calling a method such as Where, Contains or OrderBy.

LINQ 查詢表達式在定義的時候不會執行,當他們被 Where, Contains or OrderBy 修改時也不會執行。

Rather, query execution is deferred.

查詢的執行是被延遲的,它是惰性執行的。

That means that the evaluation of an expression is delayed until its realized value is actually iterated over or the ToListAsyncmethod is called.

意思就是說,表達式的求值會被延遲到真正的去遍歷或者調用了ToListAsync 方法,才會開始計算表達式的值。

For more information about deferred query execution, see Query Execution.

查看 Query Execution 以獲取更多關於表達式延遲執行的信息。

Note: The Contains method is run on the database, not in the c# code shown above.

筆記: Contains 方法會被翻譯為sql併在DB中執行,而不是在C#中調用執行。

The case sensitivity on the query depends on the database and the collation.

查詢表達式是依賴於集合或者DB對象的。

On SQL Server, Contains maps to SQL LIKE, which is case insensitive.

在 SQL Server 上,Contains 方法會被智能的映射為 SQL LIKE

In SQLlite, with the default collation, it's case sensitive.

在 SQLlite 中,他會智能的預設矯正。

Navigate to /Movies/Index.

在地址欄導航到 /Movies/Index 。

Append a query string such as ?searchString=Ghost to the URL.

在URL後追加一段像 ?searchString=Ghost 的查詢字元串。

The filtered movies are displayed.

過濾後的movie數據就顯示出來了。

If you change the signature of the Index method to have a parameter named id,

如果你更改 Index 的方法簽名,使其參數名字為 id ,

the id parameter will match the optional {id} placeholder for the default routes set in Startup.cs.

id 參數將會預設匹配 Startup.cs 文件中的 {id} 可選項參數的占位符。

 1 app.UseMvc(routes =>
 2 
 3 {
 4 
 5     routes.MapRoute(
 6 
 7         name: "default",
 8 
 9         template: "{controller=Home}/{action=Index}/{id?}");
10 
11 });
C# code

You can quickly rename the searchString parameter to id with the rename command.

你可以使用 rename 命令快速的重命名 searchString 參數為 id 。

Right click on searchString > Rename.

右擊,並選擇 > Rename 菜單。

The rename targets are highlighted.

需要重命名的目標將會全部高亮顯示,如下:

 

Change the parameter to id and all occurrences of searchString change to id.

改變參數名為 id ,下麵所有出現的 searchString 都會被命名為 id 。

 

The previous Index method:

前面的 Index 方法,如下:

 1 public async Task<IActionResult> Index(string searchString)
 2 
 3 {
 4 
 5     var movies = from m in _context.Movie
 6 
 7                  select m;
 8 
 9  
10 
11     if (!String.IsNullOrEmpty(searchString))
12 
13     {
14 
15         movies = movies.Where(s => s.Title.Contains(searchString));
16 
17     }
18 
19  
20 
21     return View(await movies.ToListAsync());
22 
23 }
C# code

The updated Index method with id parameter:

更新後的 Index 方法將帶有名為 id  的參數,如下:

 1 public async Task<IActionResult> Index(string id)
 2 
 3 {
 4 
 5     var movies = from m in _context.Movie
 6 
 7                  select m;
 8 
 9  
10 
11     if (!String.IsNullOrEmpty(id))
12 
13     {
14 
15         movies = movies.Where(s => s.Title.Contains(id));
16 
17     }
18 
19  
20 
21     return View(await movies.ToListAsync());
22 
23 }
C# code

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.

然而,你不會期望用戶每次去更改URL,當他們搜索他們想要的電影的時候。

So now you'll add UI to help them filter movies.

因此,你需要增加UI來幫助他們過濾想要的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:

如果你更改了 Index 方法的簽名來測試路由數據綁定,現在把他改回來,如下:

 1 public async Task<IActionResult> Index(string searchString)
 2 
 3 {
 4 
 5     var movies = from m in _context.Movie
 6 
 7                  select m;
 8 
 9  
10 
11     if (!String.IsNullOrEmpty(searchString))
12 
13     {
14 
15         movies = movies.Where(s => s.Title.Contains(searchString));
16 
17     }
18 
19  
20 
21     return View(await movies.ToListAsync());
22 
23 }
C# code

Open the Views/Movies/Index.cshtml file, and add the <form> markup highlighted below:

打開 Views/Movies/Index.cshtml 文件,並且添加 <form> 標簽,如下麵高亮部分所示:

 1     ViewData["Title"] = "Index";
 2 
 3 }
 4 
 5  
 6 
 7 <h2>Index</h2>
 8 
 9  
10 
11 <p>
12 
13     <a asp-action="Create">Create New</a>
14 
15 </p>
16 
17  
18 
19 <form asp-controller="Movies" asp-action="Index">
20 
21     <p>
22 
23         Title: <input type="text" name="SearchString">
24 
25         <input type="submit" value="Filter" />
26 
27     </p>
28 
29 </form>
30 
31  
32 
33 <table class="table">
34 
35     <thead>
HTML Code

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.

<form> 標簽使用了 Form Tag Helper ,因此當你提交表單時,過濾字元串被提交到了Index  方法。

Save your changes and then test the filter.

保存你的修改,然後測試搜索功能。

 

There's no [HttpPost] overload of the Index method as you might expect.

正如你所料,在 Index 方法上沒有 [HttpPost] 特征標記類。

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] ,如下的 Index 方法:

1 [HttpPost]
2 
3 public string Index(string searchString, bool notUsed)
4 
5 {
6 
7     return "From [HttpPost]Index: filter on " + searchString;
8 
9 }
C# code

The notUsed parameter is used to create an overload for the Index method.

notUsed 參數被用於創建了一個重載的 Index 方法。

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.

如果你添加這個方法,action 調用器將會匹配 [HttpPost] Index 方法,並且 [HttpPost] Index 將會執行並返回如下圖所示信息:

 

However, even if you add this [HttpPost] version of the Index method, there's a limitation in how this has all been implemented.

然而,即使你添加了 [HttpPost] 版本的 Index 方法,這也有一些限制,就是你要怎麼來實現。

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.

猜想你想標記一些詳細的搜索,或者你想給朋友發送一個連接,這個連接可以讓他們看到和你一樣的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.

註意到 HTTP POST 請求的URL與GET請求的URL完全相同,在URL上沒有檢索字元串的數據。

The search string information is sent to the server as a form field value.

檢索用的字元串被做為表單欄位上的值傳遞給伺服器。

You can verify that with the browser Developer tools or the excellent Fiddler tool.

你可以用瀏覽器開發者工具來證實。

The image below shows the Chrome browser Developer tools:

下圖展示了 Chrome 瀏覽器的開發者工具:

 

You can see the search parameter and XSRF token in the request body.

你可以在請求體中看到 搜索參數 與 XSRF 令牌。

Note, as mentioned in the previous tutorial, the Form Tag Helper generates an XSRF anti-forgery token.

註意,如前邊兒教程提到的一樣,是 Form Tag Helper 生成了 XSRF 防偽造令牌。

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.

因為查詢參數在請求體中,而不是在URL中,所以你無法捕獲查詢信息添加書簽或分享給其他人。

We'll fix this by specifying the request should be HTTP GET.

我們修複這點只需要指定請求形式為 HTTP GET 即可。

Notice how intelliSense helps us update the markup.

註意vs的智能感知如何幫助我們更新html標記。

 

 

Notice the distinctive font in the <form> tag.

註意在 <form> 標簽中的不用的字體顏色。

That distinctive font indicates the tag is supported by Tag Helpers.

不同的字體顏色指明瞭哪些受 Tag Helpers 支持。

 

Now when you submit a search, the URL contains the search query string.

現在,當你提交一個查詢的時候,URL中就在查詢字元串中包含了查詢參數。

Searching will also go to the HttpGet Index action method, even if you have a HttpPost Index method.

查詢將會直接調用 HttpGet Index ,即使已經存在了一個 HttpPost Index 方法。

 

The following markup shows the change to the form tag:

下麵的標記展示了 form 標簽的變更:

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

Adding Search by genre

添加根據流派進行搜索的功能

Add the following MovieGenreViewModel class to the Models folder:

Models 文件夾下添加 MovieGenreViewModel 類:

 1 using Microsoft.AspNetCore.Mvc.Rendering;
 2 
 3 using System.Collections.Generic;
 4 
 5  
 6 
 7 namespace MvcMovie.Models
 8 
 9 {
10 
11     public class MovieGenreViewModel
12 
13     {
14 
15         public List<Movie> movies;
16 
17         public SelectList genres;
18 
19         public string movieGenre { get; set; }
20 
21     }
22 
23 }
C# Code

The movie-genre view model will contain:

movie-genre 視圖將包含:

  • A list of movies.

一個電影列表。

  • A SelectList containing the list of genres. This will allow the user to select a genre from the list.

SelectList 將包含一系列流派,這將使用戶可以在其中選取流派。

  • movieGenre, which contains the selected genre.

movieGenre ,它包含了被選擇的流派。

Replace the Index method in MoviesController.cs with the following code:

使用下麵的代碼替換到 MoviesController.cs 文件中的 Index 方法中:

 1 // Requires using Microsoft.AspNetCore.Mvc.Rendering;
 2 
 3 public async Task<IActionResult> Index(string movieGenre, string searchString)
 4 
 5 {
 6 
 7     // Use LINQ to get list of genres.
 8 
 9     IQueryable<string> genreQuery = from m in _context.Movie
10 
11                                     orderby m.Genre
12 
13                                     select m.Genre;
14 
15  
16 
17     var movies = from m in _context.Movie
18 
19                  select m;
20 
21  
22 
23     if (!String.IsNullOrEmpty(searchString))
24 
25     {
26 
27         movies = movies.Where(s => s.Title.Contains(searchString));
28 
29     }
30 
31  
32 
33     if (!String.IsNullOrEmpty(movieGenre))
34 
35     {
36 
37         movies = movies.Where(x => x.Genre == movieGenre);
38 
39     }
40 
41  
42 
43     var movieGenreVM = new MovieGenreViewModel();
44 
45     movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync());
46 
47     movieGenreVM.movies = await movies.ToListAsync();
48 
49  
50 
51     return View(movieGenreVM);
52 
53 }
C# Code

The following code is a LINQ query that retrieves all the genres from the database.

下麵是一個 LINQ 查詢,他檢索了資料庫中的所有流派:

1 // Use LINQ to get list of genres.
2 
3 IQueryable<string> genreQuery = from m in _context.Movie
4 
5                                 orderby m.Genre
6 
7                                 select m.Genre;
C# Code

The SelectList of genres is created by projecting the distinct genres (we don't want our select list to have duplicate genres).

SelectList 由工程創建並用來給流派去重:

1 movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync())
C# Code

Adding search by genre to the Index view

將流派查詢添加到 Index 視圖上

Update Index.cshtml as follows:

用下麵代碼 更新 Index.cshtml 文件:

  1 @model MvcMovie.Models.MovieGenreViewModel
  2 
  3  
  4 
  5 @{
  6 
  7     ViewData["Title"] = "Index";
  8 
  9 }
 10 
 11  
 12 
 13 <h2>Index</h2>
 14 
 15  
 16 
 17 <p>
 18 
 19     <a asp-action="Create">Create New</a>
 20 
 21 </p>
 22 
 23  
 24 
 25 <form asp-controller="Movies" asp-action="Index" method="get">
 26 
 27     <p>
 28 
 29         <select asp-for="movieGenre" asp-items="Model.genres">
 30 
 31             <option value="">All</option>
 32 
 33         </select>
 34 
 35  
 36 
 37         Title: <input type="text" name="SearchString">
 38 
 39         <input type="submit" value="Filter" />
 40 
 41     </p>
 42 
 43 </form>
 44 
 45  
 46 
 47 <table class="table">
 48 
 49     <thead>
 50 
 51         <tr>
 52 
 53             <th>
 54 
 55                 @Html.DisplayNameFor(model => model.movies[0].Title)
 56 
 57             </th>
 58 
 59             <th>
 60 
 61                 @Html.DisplayNameFor(model => model.movies[0].ReleaseDate)
 62 
 63             </th>
 64 
 65             <th>
 66 
 67                 @Html.DisplayNameFor(model => model.movies[0].Genre)
 68 
 69             </th>
 70 
 71             <th>
 72 
 73                 @Html.DisplayNameFor(model => model.movies[0].Price)
 74 
 75             </th>
 76 
 77             <th></th>
 78 
 79         </tr>
 80 
 81     </thead>
 82 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、課程介紹 直接開門見山吧,在學習之前阿笨想問大家一句,關於WebService遠程過程調用技術(RPC) 你真的會了嗎?不要跟老夫扯什麼WebService技術已經過時,如果你的內心有在偷偷告訴你其實我是真的不會WebService的話,那麼恭喜你,因為你在這茫茫的IT編程世界里找到了這本《C# ...
  • Asp.net筆記 一、Socket類 進行網路編程的類,可以在兩台電腦之間進行網路通訊 過程: 向伺服器發送指令: GET /index.html HTTP/1.1 Host:127.0.0.1:8080 回車空行 二、瀏覽器是什麼 瀏覽器就是一個Socket網路客戶端,幫助用戶請求網站伺服器上 ...
  • using System;using System.Windows.Forms;using System.Xml;namespace winformDemo{ public partial class Form2 : Form { public Form2() { InitializeCompone ...
  • using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;u ...
  • 使用XmlReader讀Xml XmlDocument和XElement在讀取Xml時要將整個Xml文檔放到記憶體中去操作,這樣做操作簡單,但是很費記憶體和IO(可能是磁碟IO或者網路IO);而在有些場景下我們必須考慮儘可能節省記憶體和IO的開銷,這時候就該XmlReader和XmlWriter出場了。 ...
  • 使用XmlWriter寫Xml 假定創建了XmlWriter的實例變數xmlWriter,下文中將使用此實例變數寫Xml1.如何使用XmlWriter寫Xml文檔聲明 // WriteStartDocument方法可以接受一個bool參數(表示standalone,是否為獨立文檔)或者不指定參數st ...
  • 第 8 章:使用規範 8.1 數組 要在公共 API 中優先使用集合,避免使用數組。 不要使用只讀的數組欄位。雖然欄位本身是只讀的,用戶不能修改它們,但用戶可以修改數組中的元素。 考慮使用不規則數組,而不要使用多維數組。 8.2 修飾屬性 要在命名自定義修飾屬性類時添加“Attribute”尾碼。 ...
  • 18.1 使用定製特性 FCL 中的幾個常用定製特性. DllImport 特性應用於方法,告訴 CLR 該方法的實現位於指定 DLL 的非托管代碼中. Serializable 特性應用於類型,告訴序列化格式化器一個實例的欄位可以序列化和反序列化. AssemblyVersion 特性應用於程式集 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...