起飛網 ASP.NET MVC 5 學習教程目錄:
- 添加控制器
- 添加視圖
- 修改視圖和布局頁
- 控制器傳遞數據給視圖
- 添加模型
- 創建連接字符串
- 通過控制器訪問模型的數據
- 生成的代碼詳解
- 使用 SQL Server LocalDB
- Edit方法和Edit視圖詳解
- 添加查詢
- Entity Framework 數據遷移之添加字段
- 添加驗證
- Details 和 Delete 方法詳解
在本節中,我們為 Index 方法添加查詢功能,使我們能夠根據電影的題材或名稱進行查找。
修改 Index 表單
Start by updating the Index
action method to the existing MoviesController
class. Here's the code:
首先,我們需要更新 MoviesController 的 Index 方法,代碼如下:
代碼清單1:更新后的Index方法 - MoviesController.cs
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); }
Index 方法的第一行代碼創建了一個 LINQ 查詢,用來選擇符合條件的電影:
代碼清單2:選擇電影的LINQ查詢
var movies = from m in db.Movies select m;
這個查詢雖然在這里定義出來,但並沒有在數據庫中執行。
如果 searchString
參數包含一個字符串(不是空字符串),movies 查詢將會添加一個查詢字符串的過濾條件,代碼如下:
代碼清單3:添加查詢過濾條件
if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); }
代碼清單3中的 s => s.Title
是一個 Lambda 表達式,Lambda 表達式被用在基於方法的LINQ查詢中(上面代碼中的 Where 方法),當做參數來使用。LINQ 語句在定義或修改的時候不會執行,相反的,查詢會延遲執行,這意味着一個賦值語句直到迭代完成或調用 ToList 方法才具備真正的值。在上面的示例中,查詢語句在 Index.cshtml 視圖中執行。
現在,你可以修改Index 視圖,讓他展示一個表單給用戶輸入。
運行應用程序,並導航到 /Movies/Index ,在URL后面添加一個查詢,例如 ?searchString=中國
,被過濾的電影內容如下:
圖1:查詢到的電影數據
If you change the signature of the Index
method to have a parameter named id
, the id
parameter will match the{id}
placeholder for the default routes set in the App_Start\RouteConfig.cs file.
如果你把 Index 方法的參數名改為 id,那么 id 參數將會匹配 App_Start\RouteConfig.cs 文件中的默認路由中的{id}
。
{controller}/{action}/{id}
修改后的Index方法如下:
代碼清單4:修改后的 Index 方法
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); }
修改以后,我們可以通過路由數據來傳遞查詢字符串:
圖2:使用URL片段進行查找
然而,你不能指望用戶每次都通過修改URL來查找電影,因此你需要在界面上幫助他們過濾數據。如果你剛剛使用代碼清單4中的代碼測試了路由綁定是如何傳遞ID參數,現在再把它改回來,原始的代碼可參考代碼清單1。
打開Views\Movies\Index.cshtml 文件,在@Html.ActionLink("Create New", "Create")
后面添加如下代碼:
代碼清單5:修改Index.cshtml
<p> @Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()) { <p> Title: @Html.TextBox("SearchString") <br /> <input type="submit" value="Filter" /> </p
> } </p>
Html.BeginForm
幫助方法創建一個 <form>
標簽。通過單擊“Filter”按鈕將表單提交給當前的頁面。
運行應用程序,然后試着查找一個電影:
圖3:在界面中過濾數據
我們沒有為 Index 方法定義 HttpPost 的重載,因為我們根本沒有修改數據,只是做了一個查詢。
我們可以為 Index 方法添加 HttpPost 的重載,這樣一來,程序將會調用 HttpPost 修飾的 Index 方法,相應的代碼和截圖如下:
代碼清單6:HttpPost 版的 Index 方法
[HttpPost] public string Index(FormCollection fc, string searchString) { return "<h3> From [HttpPost]Index: " + searchString + "</h3>"; }
圖4:調用了 HttpPost 版本的 Index 方法
然而,盡管我們添加了HttpPost版的Index方法,它在實現的時候仍然存在一些局限性。設想你想將一個比較詳細的查詢添加書簽,或者你想將查詢結果以鏈接形式發送給朋友,注意觀察HTTP POST 請求的時候,URL是沒有改變的(仍然是 localhost:xxxxx/Movies/Index),這個地址本身不包含查詢信息。現在,查詢信息是作為表單數據發送到服務器的,這意味着你不能抓取到URL中的查詢信息,將URL作為書簽或發送給朋友。
解決方案就是重寫 BeginForm 語句,使它發送一個GET請求,從而調用HttpGet版本的Index方法,修改后的代碼如下:
代碼清單7:使用GET請求的BeginForm方法
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
圖5:使用GET請求的BeginForm參數描述
現在你再點擊“Filter”按鈕進行查找,查找的參數將包含在URL中,然后調用HttpGet 版的 Index 方法:
圖6:URL中包含了查詢參數
添加題材查詢
刪掉之前代碼中添加的 HttpPost 版的 Index方法,以后我們不再用到了。
然后,我們修改 Index 方法的代碼,使它能夠根據題材進行查詢。修改后的代碼如下:
代碼清單8:添加了題材查詢的Index方法
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); }
在修改完控制器之后,我們還需要在Index視圖中添加一個字段。在我們之前的名字查詢之前,使用 Html.DropDownList
添加一個下拉框,修改后的代碼如下:
代碼清單9:添加題材下拉列表
@using (Html.BeginForm("Index", "Movies", FormMethod.Get)) { <p>
Genre: @Html.DropDownList("movieGenre", "All"
) Title: @Html.TextBox("SearchString") <br /> <input type="submit" value="Filter" /> </p> }
代碼 @Html.DropDownList("movieGenre", "All") 生成一個下拉列表,參數 movieGenre 指明要查找的ViewBag 中的數據集合的名稱,我們在代碼8中做了標記;參數 all 是預選中的數據,我們可以使用“勵志”替換。
運行應用程序,試着根據題材和標題查詢一下:
圖7:根據題材和標題進行查找
在本節中,我們創建了查詢的方法和視圖,使用戶可以根據電影的標題和題材進行查詢。在下一節中,我們將結束如何為Movie 模型添加屬性,以及如何添加一個自動創建測試數據庫的初始值。
本文同時發布在起飛網,原文地址:http://www.qeefee.com/mvc/mvc-5-adding-search