1. 程式人生 > 其它 >ASP.NET MVC學習筆記06編輯方法和編輯檢視

ASP.NET MVC學習筆記06編輯方法和編輯檢視

上一篇中,說到了MVC生成的Index方法,和Details方法,現在來說一下自動生成的方法和檢視,應該怎麼的來進行編輯。

優化日期顯示

在這之前,先對前面的程式碼進行優化,使得釋出日期屬性(ReleaseDate)看上去更好。開啟Models/Movies.cs參考下圖進行修改。

上圖中用到了DataAnnotations。Display屬性指明要顯示的欄位的名 稱(在本例中“Release Date”來代替“ReleaseDate”)。DataType屬性用於指定型別的資料,在本例它是一個日期,所以不會顯示存放在該欄位時間詳情。DisplayFormat屬性在Chrome瀏覽器裡有一個bug:呈現的日期格式不正確。

除錯,瀏覽,然後點選一個條目,進入編輯。

如上圖所示,Edit(編輯)連結是由Views MoviesIndex.cshtml 檢視中Html.ActionLink方法所生成的.

@Html.ActionLink("Edit", "Edit", new { id=item.ID })

Html物件是一個 Helper, 以屬性的形式在System.Web.Mvc.WebViewPage基類上公開。ActionLink是一個幫助方法(Helper),便於動態生成指向Controller中操作方法 的HTML 超連結連結。ActionLink方法的第一個引數是想要呈現的連結文字 (例如,<a>Edit Me</a>

)。第二個引數是要呼叫的操作方法的名稱(在本例中, Edit方法)。最後一個引數是一個匿名物件 (anonymous object),用來生成路由資料 (在上圖中,ID 為1 的)。

因此跳轉的連結為,http://localhost:50948/movies/Edit/1,預設的路由 (在 App_StartRouteConfig.cs中設定)使用的 URL 匹配模式為: {controller}/{action}/{id}。因 此,ASP.NET 將 http://localhost:xxxxx/Movies/Edit/4轉化到 Movies 控制器中 Edit操作 方法,引數 ID等於1 的請求。所以,輸入http://localhost:50948/movies/Edit?id=1

同樣會把引數ID 等於1的請求傳給控制器的Edit方法。

控制器的Edit方法

再來看看MoviesController中的Edit的兩個方法。

注意,第二個Edit操作方法的上面有HttpPost屬性。此屬性指定了Edit方法的過載,此方法僅 被POST 請求所呼叫。可以將HttpGet屬性應用於第一個編輯方法,但不需要這樣,因為它是預設的屬性。(操作方法會被隱式的指定為HttpGet屬性,從而作為 HttpGet 方法。) 繫結(Bind)屬性是另一個重要安全機制,可以防止黑客攻擊(從over-posting資料到模型)。應該只包含在bind屬性屬性,本教程中使用的簡單模型,模型中繫結所有資料。ValidateAntiForgeryToken屬性是用來防止偽造的請求,並配對@Html.AntiForgeryToken()檔案 ( ViewsMoviesEdit.cshtml ),如下圖所示,部分在Edit View檔案:

@Html.AntiForgeryToken() 生成隱藏的窗體, 防偽令牌必須匹配Movies控制器的 Edit 方法。在教程 XSRF/CSRF Prevention in MVC,你可以讀到更多關於跨站點請求偽造 (也稱為XSRF或CSRF)。 HttpGet Edit方法會獲取電影ID引數、 查詢影片使用 Entity Framework 的Find 方法,並返回 到選定影片的編輯檢視。如果不帶引數呼叫Edit 方法,ID 引數被指定為預設值 零。如果找不到一 部電影,則返回 HttpNotFound 。當 scaffolding自動建立編輯檢視時,它會檢視Movie類併為 類的每個屬性建立用於 Render的<label><input>的元素。

注意,檢視模板在檔案的頂部有 @model MvcMovie.Models.Movie的宣告,這將指定視 圖期望的模型型別為` Movie。

scaffolded自動生成的程式碼,使用了Helper 方法的幾種簡化的 HTML 標記 。Html.LabelFor 用來顯示欄位的名稱(”Title”、”ReleaseDate”、”Genre”或”Price”)。Html.EditorFor用來呈現 HTML <input>元素。Html.ValidationMessageFor用來 顯示與該屬性相關聯的任何驗證訊息。檢視模板在檔案的頂部有 @model MvcMovie.Models.Movie的宣告,這將指定視 圖期望的模型型別為 Movie。

處理 POST 請求

回看前面的Eidt的Post方法。

ASP.NET MVC model binder接收form所post的資料,並轉換所接收的 Movie請求資料從而建立一個Movie物件。ModelState.IsValid方法用於驗證提交的表單資料是否可用於修改(編輯或更新)一個Movie物件。如果資料是有效的電影資料,將儲存到資料庫的Movies集合(MovieDBContext 例項)。通過呼叫MovieDBContext的SaveChanges方法,新的電影資料會被儲存到資料庫。資料儲存之後,程式碼會把使用者重定向到 MoviesController類的Index操作方法,頁面將顯示電影列表,同時包括剛剛所做的更新。

一旦客戶端驗證確定某個欄位的值是無效的,將顯示出現錯誤訊息。如果禁用 JavaScript,則不會有客戶端驗證,但伺服器將檢測回傳的值是無效的,而且將重新顯示 表單中的值與錯誤訊息。在本教程的後面,我們驗證更詳細的審查。 Edit.cshtml 檢視模板 中的 Html.ValidationMessageFor Helper將用來顯示相應的錯誤訊息。

所有 HttpGet方法遵循類似的模式。他們得到一個電影物件(或物件列表中,如本案例的 Index),並把模型資料傳遞給檢視。Create方法傳遞一個空的影片物件給Create檢視。 所有的 create, edit, delete方法,或其他的方法: 用HttpPost過載的方法修改資料。修改 資料在HTTP GET方法, 存在安全風險。在HTTP GET方法中修改資料也違反HTTP 的最佳實踐和REST模式架構,指明GET請求不應該改變你的應用程式的狀態。換句話說,執行GET操作應該是一個安全,操作,無任何副作用,不會修改你的持久化資料。

按照電影流派新增搜尋

首先,如果之前添加了 HttpPost 的Index方法,請立即刪除它。

下面,通過一些列的修改,來讓使用者可以通過流派來搜尋電影。先從Controller中的index方法開始。

這個版本的 Index方法將接受一個附加的 movieGenre引數。前幾行的程式碼會建立一個 List物件來儲存資料庫中的電影流派。

下面的程式碼是從資料庫中檢索所有流派的 LINQ 查詢:

var GenreQry = from d in db.Movies  
                   orderby d.Genre  
                   select d.Genre;

該程式碼使用泛型 List集合的 AddRange方法將所有不同的流派,新增到集合中的。(使 用 Distinct修飾符,不會新增重複的流派 – 例如,在我們的示例中添加了兩次喜劇)。

該程式碼然後在ViewBag物件中儲存了流派的資料列表。的SelectList物件在ViewBag作 為儲存類資料(這樣的電影流派),然後在下拉列表框中的資料訪問類別,是一個典型的MVC applications的方法。 下面的程式碼演示如何檢查 movieGenre引數。如果它不是空的,程式碼進一步指定了所查詢的電影流派。

if (!string.IsNullOrEmpty(movieGenre)) 
 { 
    movies = movies.Where(x => x.Genre == movieGenre); 
 }

如前所述,查詢資料不會在資料庫上執行,直到電影列表迭代結束(恰發生在View, Index方法返回後)。

注意:這個地方用到了LinQ的知識,如果對LinQ不太瞭解的,可以查閱官方文件.

Index檢視新增標記

ViewsMoviesIndex.cshtml檔案中,新增Html.DropDownList輔助方法,在TextBox前。完成的程式碼如下圖所示:

下面的程式碼:

@Html.DropDownList("movieGenre", "All")

ViewBag中,”movieGenre“ 參考作為key在DropDownList中搜索 IEnumerable<SelectListItem > .

ViewBag填入的操作方法: 引數“All”提供的項列表中的預先選擇的。如我們使用下面的程式碼:

@Html.DropDownList("movieGenre", "Comedy")

在我們的資料庫中,我們擁有與“喜劇”流派的電影,“喜劇”在下拉列表中將預先選 擇。因為我們沒有一個電影流派“All”,也沒有“All”的 SelectList,所以當我們post back後不做任何選擇,movieGenre查詢字串值是空的。 執行應用程式並瀏覽 /Movies/Index。嘗試搜尋流派,來檢索資訊。

在本篇中,建立了一個搜尋的方法和檢視,使用它,使用者可以通過電影標題和流派來搜 索。在下一篇中,將看到如何新增一個屬性到 Movie model,和如何新增一個初始值設定項值,它會自動建立一個測試資料庫。