譯者註:本節內容實際上是原英文教程第六節的後半部分,因感覺第六節內容較長,本部分內容與上區段標頭(添加Edit方法和視圖)無關,在項目開發中搜尋功能既常見又常用,在此拿出來作為單獨章節。
本節課程中,你將添加一個SearchIndex 方法,使你可以通過片名來搜尋影片。 /Movies/SearchIndex地址將可用。該請求將顯示一個包含使用者可以輸入的input元素的表單來尋找影片。當使用者提交表單後,該方法將得到使用者提交的搜尋值並用於搜尋資料庫。
首先在現有的MoviesController類中增加一個SearchIndex方法。該方法將返回包含Html表單的視圖。以下為代碼:
public ActionResult SearchIndex(string searchValue) { //linq方式,查詢所有影片,僅定義,不執行 var movies = from m in db.Movies select m; if (string.IsNullOrEmpty(searchValue) == false) { //基於linq查詢結果的Lambda運算式,調用where方法後執行linq movies = movies.Where(m => m.Name.Contains(searchValue)); } return View(movies); }
查詢操作是順延強制的,意味著運算式的值運算直到值被遍曆或者調用ToList方法才會被執行。在這個例子中,查詢是在SearchIndex視圖中執行的。想瞭解更多關於查詢順延強制方面的資訊,請參見Query Execution。
現在你可以實現 SearchIndex視圖,由它來呈現使用者表單。在SearchIndex方法內部按右鍵,選擇添加視圖。在對話方塊中,勾選“建立強型別視圖”,然後指定你將傳遞Movie對象給視圖模板作為它的模型類。在支架模板列表中,選擇List後點擊添加,如所示
點擊添加按鈕後,視圖模板Views\Movies\SearchIndex.cshtml將被建立。因為你選擇了支架模板中的List,Visual Studio在視圖中自動產生一些預設標記。支架系統查看Movie類並為其每個屬性建立了<Label>屬性元素,形成HTML表單。以下為視圖檔案:
View Code
@model IEnumerable<MvcMovie.Models.Movie>@{ ViewBag.Title = "SearchIndex";}<h2>SearchIndex</h2><p> @Html.ActionLink("Create New", "Create") </p><table> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Genra) </th> <th> @Html.DisplayNameFor(model => model.Price) </th> <th> @Html.DisplayNameFor(model => model.Date) </th> <th></th> </tr>@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Genra) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Date) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID }) </td> </tr>}</table>
運行程式,導航到/Movies/SearchIndex.,在地址後附加一個類似“?searchValue=少年”的查詢字串,會將過濾後的結果顯示出來。
如果你改變SearchIndex 方法的簽名,使參數標識符為ID,則參數ID將與在Global.asax檔案中設定的預設路由匹配{controller}/{action}/{id},即把SearchIndex的形參 searchValue修改為ID。現在你可以傳遞搜尋名稱作為路由資料替代查詢字串方式,即採用以下方式訪問http://localhost:5279/Movies/SearchIndex/少年。
然而,你不能期望使用者為了搜尋影片而每次去修改url。因此,添加互動介面(UI)來協助他們過濾影片。如果你上文中對SearchIndex的方法簽名進行了修改,用來測試通過路由綁定方式來傳遞ID參數,那麼改回來,即方法擁有一個名稱為searchValue的字串型別參數。
開啟Views\Movies\SearchIndex.cshtml檔案,在@Html.ActionLink("Create New", "Create")代碼後添加如下代碼
@using (Html.BeginForm()){ <p> 片名: @Html.TextBox("searchValue")<br /> <input type="submit" value="查詢" /></p> }
Html.BeginForm方法將建立<form>標記。使用者通過點擊“查詢”按鈕提交表單。運行程式並嘗試查詢影片。
實際並沒有標記為HttpPost屬性的SearchIndex的方法。因為該方法並沒有修改應用的狀態,僅僅是過濾資料,因此不需要HttpPost屬性的重載方法。
譯者註:此處有個問題想不通。按上文所述,預設的SearchIndex方法屬性是HttpGet,在視圖中使用Html.BeginForm(),運行程式後,查看頁面原始碼,發現預設是<form action="/Movies/SearchIndex" method="post">,也即使用者點擊按鈕後,是通過post方式把表單傳遞過來的,為啥會調用上面接受HttpGet方式的SearchIndex方法?難道是優先找HttpPost屬性,找不到的情況下提交給HttpGet處理?這是Http協議機制還是MVC機制處理的結果?
你可以添加下面的HttpPost屬性的SearchIndex 方法。在這種情況下,方法調用將匹配HttpPost方式,下面的方法將被執行。
[HttpPost] public string SearchIndex(FormCollection frm, string searchValue) { return "<h3> 表單HttpPost方式搜尋 : " + searchValue + "</h3>"; }
但是,即使你添加了SearchIndex的HttpPost版本的方法,使用的時候仍然存在限制。試想一下,你要得到一個特定的搜尋書籤,或者你想發送一個連結給朋友,他們可以通過點擊看到與你相同的過濾後的電影列表。注意post請求的url和get請求的url完全相同,在地址欄沒有搜尋資訊。搜尋的文本資訊作為表單域值送到伺服器。因此你不能擷取包含搜尋資訊的書籤或者發給朋友一個連結。
解決方式就是使用BeginForm的重載方法,指明post請求添加搜尋資訊到url地址,並路由到HttpGet版本的SearchIndex 方法。使用以下代碼替換已存在的BeginForm 方法
@using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get))
現在當你提交搜尋時,url將包含查詢字串。即使存在HttpPost屬性的SearchIndex方法,搜尋工作也將由HttpGet屬性的SearchIndex方法處理。
譯者註:以上為原文翻譯的結果。譯者感覺存在邏輯矛盾的地方。使用Html.BeginForm的重載方法,指定了FormMethod.Get參數,也即是將表單的提交方式由預設的post方式變更為Get,自然就會去調用HttpGet屬性的SearchIndex方法。
譯者註:原文進一步舉了一個使用影片風格下拉式清單作為查詢條件的例子,與上大都相同,僅細節稍微有所差異,做刪節處理,感興趣的可查看原文。
在本節中,你建立了搜尋方法和視圖,讓使用者可以通過影片名稱搜尋資料庫。在下節中,你將學習如何給Movie模型添加一個屬性,以及如何添加一個初始化器,用來自動建立測試資料庫。
本教程所有文章導航
本系列共10篇文章,翻譯自Asp.Net MVC4 官方教程,由於本系列文章言簡意賅,篇幅適中,從一個樣本開始講解,全文最終完成了一個管理影片的小系統,非常適合新手入門Asp.Net MVC4,並由此開始開發工作。
原文供9篇文章,譯者將其中第6篇拆成了2篇
1. Asp.Net MVC4 入門介紹
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/03/2800210.html
2. 添加一個控制器
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-controller
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801949.html
3. 添加一個視圖
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-view
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801988.html
4. 添加一個模型
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-model
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803012.html
5. 從控制器訪問資料模型
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/accessing-your-models-data-from-a-controller
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803429.html
6.查看Edit方法和Edit視圖
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-methods-and-edit-view
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2804100.html
http://www.cnblogs.com/seawaving/archive/2012/12/06/2804590.html
7. 為Movie模型和庫表添加欄位
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-new-field-to-the-movie-model-and-table
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2805401.html
8. 為模型添加驗證
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-validation-to-the-model
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2806322.html
9. 查看Detail和Delete方法
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-details-and-delete-methods
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/10/2811064.html