改善 Details 和 Delete 方法 (VB)
本教學課程將說明基本概念,簡介如何使用 Microsoft Visual Web Developer 2010 Express Service Pack 1 (Visual Studio Microsoft 的免費版本) 建置 ASP.NET MVC Web 應用程式。 開始之前,請確定您已安裝下列必要項目。 您可按以下連結安裝所有專案:Web Platform Installer。 或者可使用下列連結個別安裝必要條件:
- Visual Studio Web Developer Express SP1 必要條件
- ASP.NET MVC 3 工具更新
- SQL Server Compact 4.0 (執行階段 + 工作支援)
如果您使用 Visual Studio 2010 而非 Visual Web Developer 2010,請按以下連結安裝必要條件:Visual Studio 2010 必要條件。
本主題隨附內含 VB.NET 原始程式碼的 Visual Web Developer 專案。 下載 VB.NET 版本。 如果您偏好使用 C#,請改參閱本教學課程的 C# 版。
在本教學課程的這部分,您將瞭解如何改善自動產生的 Details
和 Delete
方法。 這些變更不是必要步驟,但只要使用一小段程式碼,就可以輕鬆增強應用程式。
改善 Details 和 Delete 方法
當您建構 Movie
控制器之後,ASP.NET MVC 產生的程式碼運作良好,但您希望能提升健全度,只要進行一小部分的調整就能做到。
開啟 Movie
控制器並修改 Details
方法,在找不到電影時傳回 HttpNotFound
。 您也應該修改 Details
方法,對傳遞至該方法的識別碼設定預設值。 (您在本教學課程的 第 6 部分,也曾對 Edit
方法做過類似變更)。不過,您必須將 Details
方法的傳回類型從 ViewResult
變更為 ActionResult
,因為 HttpNotFound
方法不會傳回 ViewResult
物件。 以下範例呈現已修改的 Details
方法。
Public Function Details(Optional ByVal id As Integer = 0) As ActionResult
Dim movie As Movie = db.Movies.Find(id)
If movie Is Nothing Then
Return HttpNotFound()
End If
Return View(movie)
End Function
Code First 可讓您使用 Find
方法輕鬆搜尋資料。 此方法內建重要的安全性功能,即程式碼會先驗證 Find
方法是否已找到電影,然後才嘗試執行任何動作。 比方說,駭客可能會將透過 http://localhost:xxxx/Movies/Details/1
連結建立的 URL 變更為類似 http://localhost:xxxx/Movies/Details/12345
(或不代表實際電影的其他值),導致站台發生錯誤。 若未檢查 Null 電影,可能會導致資料庫錯誤。
同樣地,請變更 Delete
和 DeleteConfirmed
方法,指定 ID 參數的預設值,並在找不到電影時傳回 HttpNotFound
。 Movie
控制器中已更新的 Delete
方法如下所示。
' GET: /Movies/Delete/5
Public Function Delete(Optional ByVal id As Integer = 0) As ActionResult
Dim movie As Movie = db.Movies.Find(id)
If movie Is Nothing Then
Return HttpNotFound()
End If
Return View(movie)
End Function
'
' POST: /Movies/Delete/5
<HttpPost(), ActionName("Delete")>
Public Function DeleteConfirmed(Optional ByVal id As Integer = 0) As ActionResult
Dim movie As Movie = db.Movies.Find(id)
If movie Is Nothing Then
Return HttpNotFound()
End If
db.Movies.Remove(movie)
db.SaveChanges()
Return RedirectToAction("Index")
End Function
請注意,Delete
方法不會刪除資料。 如果您執行刪除作業以回應 GET 要求 (或是執行相關編輯作業、建立作業或任何會變更資料的其他作業),則會造成安全性漏洞。
我們將可刪除資料的 HttpPost
方法命名為 DeleteConfirmed
,以提供 HTTP POST 方法的唯一簽章或名稱。 這兩個方法簽章如下所示:
Public Function Delete(Optional ByVal id As Integer = 0) As ActionResult
<HttpPost(), ActionName("Delete")>
Public Function DeleteConfirmed(Optional ByVal id As Integer = 0) As ActionResult
通用語言執行平台 (CLR) 需要多載方法,以提供唯一簽章 (方法名稱相同但參數清單不同)。 不過,這裡還會用到兩個 Delete 方法 (分別用於 GET 和 POST),且兩者都有相同的簽章。 (它們都需要接受單一整數作為參數)。
若要解決此問題,您可以執行幾項動作。 其一是指定不一樣的方法名稱。 這是我們在前述範例的作法。 不過,這麼做會導致一個小問題:ASP.NET 會依名稱將 URL 區段與動作方法對應,一旦您重新命名方法,路由通常就會找不到這個方法。 解決辦法正如您看到的這個範例:將 ActionName("Delete")
屬性新增至 DeleteConfirmed
方法。 此方法會有效執行路由系統的對應,以便 POST 要求中含有 /Delete/ 的 URL 找到 DeleteConfirmed
方法。
避免方法同名問題的另一個解方,是以人工方式變更 POST 方法的簽章,並加入未使用的參數。 例如,有些開發人員會新增參數類型 FormCollection
並傳遞至 POST 方法,然後就不使用參數:
Public Function Delete(ByVal fcNotUsed As FormCollection, Optional ByVal id As Integer = 0) As ActionResult
Dim movie As Movie = db.Movies.Find(id)
If movie Is Nothing Then
Return HttpNotFound()
End If
db.Movies.Remove(movie)
db.SaveChanges()
Return RedirectToAction("Index")
End Function
結語
現在您已有一個完整的 ASP.NET MVC 應用程式,資料則儲存在 SQL Server Compact 資料庫中。 您可建立、讀取、更新、刪除和搜尋電影。
本基本教學課程可協助您開始製作控制器、建立控制器與檢視的關聯,以及傳遞硬式編碼資料。 接著,您建立並設計資料模型。 Entity Framework Code First 會從資料模型即時建立資料庫,而 ASP.NET MVC Scaffolding 系統會自動產生基本 CRUD 作業的動作方法和檢視。 接著您新增了搜尋表單,讓使用者搜尋資料庫。 您變更資料庫以納入新的資料行,然後更新兩個頁面,以建立及顯示這項新資料。 您已使用 DataAnnotations
命名空間中的屬性標記資料模型,以新增驗證。 產生的驗證會在用戶端和伺服器上執行。
如果您想部署應用程式,建議先在本機 IIS 7 伺服器上測試。 您可以使用此 Web Platform Installer 連結,啟用 ASP.NET 應用程式的 IIS 設定。 請參閱下列部署連結:
在此建議您繼續參閱中級程度的教學課程 (為 ASP.NET MVC 應用程式建立 Entity Framework 資料模型和「MVC Music 市集),並且瀏覽 MSDN 上有關 ASP.NET 的文章,以及善用 https://asp.net/mvc 的豐富影片和資源,深入瞭解 ASP.NET MVC! ASP.NET MVC 論壇是提問的絕佳平台。
敬祝您使用愉快!
— Scott Hanselman (http://hanselman.com 和 Twitter 上的 @shanselman);Rick Anderson blogs.msdn.com/rickAndy