在這一小節,我們將會創建一個新的MoviesController類並且寫代碼來檢索movie有關的數據,最后使用視圖模板來進行展示。
在繼續下一步之前,然我們先將程序生成以下。
右鍵單擊Controllers文件夾創建一個新的MovieController,如果你沒有先生成一下(右鍵單擊項目,Build)的話,下面這些選項是不會出現的:
- Controller name:MoviesController。
- Template:MVC Controller with read/write actions and views,using Entity Framework。
- Model class:Movie(MvcMovie.Models)。
- Data context class:MovieDBContext(MvcMovie.Models)。
- Views:Razor(CSHTML)。
點擊“Add”,Visual Studio將會創建如下的文件和文件夾:
- 在項目的Controllers文件夾下新建MoviesController.cs文件
- 在項目的Views文件夾下新建Movies文件夾。
- 在新的Views\Movies文件夾下新建Create.cshtml,Delete.cshtml,Details.cshtml,Edit.cshtml和Index.cshtml
ASP.NET MVC 4會自動創建CRUD(create,read,update和delete)的action方法和視圖(自動創建crud action和視圖的行為被稱之為scaffolding)。現在我們有了一個完整功能的web應用,可以讓我們對電影數據進行創建,編輯,瀏覽和刪除。
運行程序通過在地址欄的URL后面添加/Movies來訪問MoviesController。因為我們的應用程序依賴於默認的路由規則(定義在Global.asax文件里),請求http://localhost:xxxx/Movies時會被自動路由到MoviesController的Index action方法。換句話說,請求http://localhost:xxxx/Movies和請求http://localhost:xxxx/Movies/Index是一樣的。返回的結果是一個空的列表,因為我們現在還沒有任何數據。
新建一個Movie
選擇Create New超鏈接。輸入一部電影的細節數據然后單擊Create按鈕。
單擊Create按鈕使表單提交到服務器,服務器會將movie的數據保存到數據庫中。然后再次瀏覽/Movies,這次可以看到新添加的數據了。
多創建一些數據,試一試Edit,Details和Delete超鏈接,這些都是可用的。
來看看生成的代碼
打開Controllers\MoviesController.cs文件來查看一下生成的Index方法。下面展示了MoviesController中的一部分代碼.
public class MoviesController : Controller
{
private MovieDBContext db = new MovieDBContext();
//
// GET: /Movies/
public ActionResult Index()
{
return View(db.Movies.ToList());
}
下面的代碼實例化了一個前面提到過的MovieDbContext對象,是movie數據庫的上下文,你可以使用它了查詢,編輯和刪除數據。
private MovieDBContext db = new MovieDBContext();
對MoviesController的請求會返回數據庫中Movies表的所有數據並且將這些數據傳遞到Index的view中。
強類型模型和@model關鍵字
在前面的文章里,我們知道了一個controller如何通過ViewBag對象來為View模板傳遞數據。ViewBag對象是一個動態對象,可以提供一種方便的,晚期綁定的方式來為view傳遞數據。
ASP.NET MVC同樣提供了為View模板傳遞強類型數據的能力。這種強類型數據提供了更好編譯時的代碼檢查和Visual Studio的智能提示。scaffolding機制使用了這種方法來創建MoviesController和視圖模板中的方法和view。
在Controllers\MoviesController.cs文件中查看生成的Details方法,MoviesController中Details方法的代碼如下。
// // GET: /Movies/Details/5 public ActionResult Details(int id = 0) { Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); }
如果能找到指定id的數據,一個Movie對象的實例就會傳遞給Deatils的視圖。來看一下Views\Movies\Details.cshtml文件。
通過在視圖模板頂部引入@model語句我們可以指定視圖期望使用的對象類型。當我們創建Moviescontroller的時候,Visual Studio自動在Details.cshtml文件的頂部包含了下面的語句
@model MvcMovie.Models.Movie
@model指令允許我們通過強類型的的Model對象來訪問Controller傳遞給View的電影數據。例如,在Details.cshtml模板里,代碼中通過強類型的Model對象向DisplayNameFor和DisplayFor方法傳遞需要的Movie對象的數據。Create和Edit方法還有視圖模板中都是傳遞的Movie類型的Model對象。
讓我們仔細查看一下Index.cshtml和MoviesController.cs里定義的Index方法里的內容,注意一下Index方法中的代碼中在調用View方法時是如何創建List對象的,代碼把創建的List對象從controller傳遞到了view。
public ActionResult Index() { return View(db.Movies.ToList()); }
當創建MoviesController的時候,Visual Studio會自動在Index.cshtml頁面頂部添加@model語句
@model IEnumerable<MvcMovie.Models.Movie>
這條@model指令允許我們通過使用強類型的Model對象訪問controller傳遞給view的數據。例如,在Index.cshtml模板里,代碼通過一個foreach語句遍歷Model對象。
@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Genre) </td> <td> @Html.DisplayFor(modelItem => item.Price) </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> }
因為Model對象是強類型的(是IEnumerable<Movie>對象),在foreach循環中的item是Movie類型。這就是說我們可以獲得編譯時安全檢查和VS的智能提示的支持。
與數據庫一起工作
注:原文使用Visual Studio 2012自帶的Sql Server LocalDB數據庫,本文使用的是Visual Stuio 2010自帶的Sql Server Express
Entity Framework的Code First模式會探測到數據庫連接字符串指向了還不存在的Movies數據庫,所以Code First會自動創建這個數據庫。你可以通過查看App_Data文件夾來驗證這一點。如果你看不到Movies.mdf文件,單擊解決方案資源管理器上方工具條中的"Show All Fiels"按鈕,單擊"Refresh"按鈕,然后展開App_Data文件夾.
雙擊Movies.mdf來打開數據庫瀏覽器,展開Tables文件夾來看一下Movie表
右鍵單擊Movies表選擇"Show Table Data"來查看我們創建的數據
右鍵單擊Movies表,選擇"Open Table Definition"來看一下Entity Framework Code First來為我們創建的表結構
注意Movies表結構是如何與我們之前創建的Movie類對應起來的。Entity Framework Code First根據Movie類自動創建表結構.
當你完成這些操作的時候,右鍵單擊數據庫選擇"Close Connection",如果不這么做的話,下次打開項目可能會報錯.
現在我們有了一個簡單的頁面來展示數據庫里的數據了。在下一篇文章里,我們將會查看剩余的自動生成的代碼,並且添加一個SearchIndex方法和一個SearchIndex視圖來查找數據庫里的數據。