在這一章節中,我們將創建一個新的MoviesController類,寫代碼獲取movie數據並用視圖模板將它們顯示到瀏覽器中。
在我們進行下一操作之前先Build the application。如果你沒有編譯該應用程序,我們添加一個controller時候編譯器會報錯。
在Solution Explorer,在Controllers文件夾上右擊,點擊Add, 然后選擇Controller.
在Add Scaffold對話框中,選擇MVC 5 Controller with views, using Entity Framework, 然后點擊Add.
- 給Controller命名為 MoviesController.
- 給Model Class選擇Movie(MvcMovie.Models).
- 給Data context類選擇MovieDBContext(MvcMovie.Models).
完成后的對話框顯示如下:
點擊Add.(如果你得到錯誤,很有可能是在添加controller的時候沒有編譯.)到此,VS幫你創建了如下文件和文件夾:
- 在Controllers文件夾下創建了一個MovieController.cs文件。
- 創建了一個新的Views\Movies文件夾。
- 在Views\Movies文件夾下創建了Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml和Index.cshtml文件。
此時VS自動給你創建好了CRUD(Create, Read, Update and Delete)action方法和視圖(這些自動創建號的CRUD action方法和視圖就被作為是scaffolding).現在你已經有了一個能夠讓你添加,刪除,修改,查看Movie實體的全功能Web應用程序了。
運行應用程序,點擊MVC Movie鏈接(或者通過在你的瀏覽器地址欄里追加/Movies來瀏覽Movies控制器)。因為你的應用程序依賴於默認的路由配置(定義在App_Start\RouteConfig.cs文件里),瀏覽器向服務器請求http://localhost:xxxx/Movies,結果被路由到了Movies controller中默認的Index方法中。換句話說,瀏覽器請求的http://localhost:xxxx/Movies 和請求http://localhost:xxxx/Movies/Index 的效果是一樣的。結果是一個空的Movies列表,因為你並沒有添加任何Movie.
1. 創建一個Movie
選擇Create New鏈接,輸入給movie輸入一些詳細信息,然后點擊Create按鈕。
注意:
在Price字段,你也許沒有輸入小數點('.')或者逗號(',').為了給用逗號(',')替代小數點,用非美式的日期格式的非英語環境支持JQuery驗證,你必須保護globalize.js和具體的cultures/globalize.culture.js文件(可以從https://github.com/jquery/globalize獲得),並且在Javascript使用Globalize.parseFloat方法。在下面的章節中我將向你顯示如何操作。至此,我們僅輸入10。
點擊Create按鈕將導致該表單提交到服務器,也就是movie信息被保存進數據庫的地方。然后你將被重定向到/Movies URL, 此時你就可以在列表中看到你新添加的movie了。
創建更多的movie實體,嘗試Edit, Details, 和Delete的功能能不能起作用。
2. 檢查產生的代碼
打開Controller\MoviesController.cs文件,檢查產生的Index方法。movie controller中的Index方法的部分代碼顯示如下:
1 public class MoviesController : Controller 2 { 3 private MovieDBContext db = new MovieDBContext(); 4 5 // GET: /Movies/ 6 public ActionResult Index() 7 { 8 return View(db.Movies.ToList()); 9 }
一個要求返回Movies數據表中的所有項,然后把結果傳遞給Index視圖的請求發向Movies controller.下面的行來自於MoviesController類,作用是實例化一個movie數據上下文。在query,edit和delete Movies時你會用到這個數據上下文實例。
1 private MovieDBContext db = new MovieDBContext();
3. 強類型Models和@model關鍵字
在這本教程的早期,你看到我們如何使用ViewBag對象將數據從一個controller當中傳遞給視圖模板。ViewBag是一個動態類型,能夠提供一種方便后期邦定的方式將數據信息傳遞給視圖。
MVC也有這種能力,就是將一個強類型對象傳遞給視圖模板。強類型方式能夠更好的在編譯時檢查你的代碼,並在VS編譯器中提供更豐富的智能感知能力。VS中的scaffolding機制當他在MoviesController類中創建方法和視圖的時候也是使用這種方式。
在Controllers\MoviesController.cs文件檢查Details方法,Details方法內容如下:
1 public ActionResult Details(int? id) 2 { 3 if (id == null) 4 { 5 return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 6 } 7 Movie movie = db.Movies.Find(id); 8 if (movie == null) 9 { 10 return HttpNotFound(); 11 } 12 return View(movie); 13 }
id參數被作為路由數據來傳遞,例如:http://localhost:xxxx/movies/details/1 將設置controller為movie controller,阿action方法為details和id為'1'.你也可以使用如下的query string來傳遞:
http://localhost:xxxx/movies/details?id=1
如果一個movie被找到了, Movie模型的實例就會被傳遞給Details視圖:
1 return View(movie);
檢查Views\Movies\Details.cshtml文件中的內容:
1 @model MvcMovie.Models.Movie 2 3 @{ 4 ViewBag.Title = "Details"; 5 } 6 7 <h2>Details</h2> 8 9 <div> 10 <h4>Movie</h4> 11 <hr /> 12 <dl class="dl-horizontal"> 13 <dt> 14 @Html.DisplayNameFor(model => model.Title) 15 </dt> 16 @*Markup omitted for clarity.*@ 17 </dl> 18 </div> 19 <p> 20 @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) | 21 @Html.ActionLink("Back to List", "Index") 22 </p>
通過在視圖文件頂部添加@model,你就可以給視圖添加你所期望的對象類型。當你創建一個movie controller的時候,VS將自動把@model語句包含到Details.cshtml文件的頂部。
1 @model MvcMovie.Models.Movie
這@model能夠使你將controller中的movie使用強類型的Model對象傳遞給視圖。例如,在Details.cshtml模板中,通過強類型的Model對象給movie的每一個字段的值傳入給DisplayNameFor和DisplayFor HTML Helpers。在Create和Edit方法與相應的視圖模板也傳遞了一個強類型的movie model對象。
檢查Index.cshtml視圖模板和MoviesController.cs文件中的Index方法。注意:當在Index action方法中調用View的Helper方法時如何用代碼創建一個List對象。這段代碼能夠將Movies列表從Index方法傳遞給視圖。
1 public ActionResult Index() 2 { 3 return View(db.Movies.ToList()); 4 }
當你創建一個movie controller的時候,VS將自動的下面的@model語句包含到Index.cshtml文件頂部:
1 @model IEnumerable<MvcMovie.Models.Movie>
@model表明允許你能夠訪問通過使用Model對象(強類型)從Controller傳遞到View中的movies列表信息。例如:在Index.cshtml模板,通過對強類型的Model對象使用foreach語句,遍歷movies。
1 @foreach (var item in Model) { 2 <tr> 3 <td> 4 @Html.DisplayFor(modelItem => item.Title) 5 </td> 6 <td> 7 @Html.DisplayFor(modelItem => item.ReleaseDate) 8 </td> 9 <td> 10 @Html.DisplayFor(modelItem => item.Genre) 11 </td> 12 <td> 13 @Html.DisplayFor(modelItem => item.Price) 14 </td> 15 <th> 16 @Html.DisplayFor(modelItem => item.Rating) 17 </th> 18 <td> 19 @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | 20 @Html.ActionLink("Details", "Details", { id=item.ID }) | 21 @Html.ActionLink("Delete", "Delete", { id=item.ID }) 22 </td> 23 </tr> 24 }
因為Model對象是強類型(實際上是IEumerable<Movie>對象),在循環中的每一個item對象就是一個Movie。另外幾個好處是,意味着你可以編譯時檢查代碼和在代碼編譯器中有富智能提示的支持。
4. 與SQL Server LocalDB的協同合作
EF框架中的Code First檢測用來指示Movies DB的數據庫連接串實際上並不存在,所以Code First自動創建了這個數據庫。你可以驗證一下該數據庫在App_Data文件夾下並沒有被創建。如果你沒有看到Movies.mdf文件,可以在Solution Explorer工具欄上點擊Show All Files, 再點擊Refresh按鈕,然后再打開App_Data文件夾。
雙擊Movies.mdf打開SERVER EXPLORER,然后打開Tables文件夾來查看Movies數據表。默認的情況下主鍵的圖標臨近ID,EF將是命名為ID的屬性作為主鍵。如果想獲得更多的關於EF和MVC的信息,請查看教程MVC and EF.
在Movies表上右擊,選擇Show Table Data來查看你所創建的數據。
在Movies表上右擊,選擇Open Table Definition來查看EF框架通過Code First給你創建好的表的結構。
注意:
Movies表的架構是如何印射到你剛才創建的Movie類的。EF框架將自動的根據你的Movie類創建者中架構。
當你完成這些操作的時候,通過在MovieDBContext上右擊,選擇Close Connection來關閉數據庫的連接。(如果你沒有關閉這個連接,當你下次再運行這個項目的時候程序會報錯)
到此為止,你已經有了一個能夠進行增、刪、改查的數據庫和頁面了。在下面的教程中,我們將檢查scaffolded代碼並添加一個SearchIndex方法和SearchIndex視圖以便能夠讓你在數據庫中查詢movies。想了解能夠信息,請查看Creating an Entity Framework Data Model for an ASP.NET MVC Application