[ASP.NET MVC] 從Controller取得Model的資料

[ASP.NET MVC] 建立Controller取得Model的資料傳遞到View上,在瀏覽器顯示畫面。

建立MoviesController

接下來將建立一個新的MoviesController Class,並使用 View 將電影的資料顯示在瀏覽器上。

在新增Controller之前,先建置方案,以避免新增Controller時,出現錯誤。

在方案總管中的Controllers 資料夾按下右鍵,選擇 加入>控制器。

新增Scaffold 中,選擇具有檢視、使用 Entity Framework 的 MVC 5 控制器,按下新增

 

  • 模型類別中選擇 Movie (MvcMovie.Models) 

  • 資料內容類別中選擇MovieDBContext (MvcMovie.Models)

  • 控制器名稱中輸入 MoviesController

下圖為輸入完成的畫面

 

點擊加入(要是顯示錯誤訊息的話,請先建置方案),Visual Studio將會產生以下檔案與資料夾:

一個在Controllers資料夾中的 MoviesController.cs。

一個Views\Movies資料夾。

在新的Views\Movies資料夾中有Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, and Index.cshtml 等。

 

加入後,Visual Studio便自動建立了CRUD(Create新增、Read讀取、Update修改、Delete刪除) 的方法與View。現在,應用程式便可以顯示與操作新增、編輯、刪除電影明細了。

執行應用程式並點擊左上方的 "我的電影" 連結(或是在網址列結尾加上 /Movies ,指到Movies的controller)。網址http://localhost:xxxxx/Movies會依照預設的路由(於App_Start\RouteConfig.cs 中定義)呼叫MoviesController裡的Index方法。也就是說,輸入網址http://localhost:xxxxx/Movieshttp://localhost:xxxxx/Movies/Index是一樣的效果。

打開後的電影列表是空的。

新增一個電影

點擊Create New連結,輸入電影資料後,按下Create 按紐。

按下Create 按鈕後,表單的電影資料將會被傳遞到server端,儲存進資料庫中。接著重新指向/Movies路徑,便會在index中看到剛剛新增的電影明細了。

你可以在建立更多的電影明細,並試著點擊EditDetails, 和Delete的連結,具備了完整的編輯、讀取明細與刪除的作用。

 

檢視程式碼

接著,來看看剛剛產生的程式碼

開啟Controllers\MoviesController.cs檔,看到MoviesController 中的 Index 方法如下。

public class MoviesController : Controller
{
   private MovieDBContext db = new MovieDBContext();

   // GET: Movies
   public ActionResult Index()
   {
     return View(db.Movies.ToList());
   }

 

MoviesController 返回所有輸入於Movies 資料表中的資料,並傳遞到Index View 顯示。

MoviesController Class中的最上方,如下行程式。實體化了一個Movie的database context,可以用來查詢、編輯、刪除movie的資料。                       

private MovieDBContext db = new MovieDBContext();

 

強型別的Models與@model

在之前提到,Controller使用ViewBag物件傳遞資料到View做顯示。
ViewBag是一個dynamic型別,dynamic 在編譯時不會做檢查,沒有 Intellisense,也不會顯示有錯誤。要到執行時期時才會檢查。

MVC也提供強別的物件傳遞給View。這種強行別可以在編寫程式時,在Visual Studio的IntelliSense顯示。

在 Controllers\MoviesController.cs裡找到Details的方法,如下

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

使用id參數,如:http://localhost:1234/movies/details/1,將會設置MoviesController的Details方法中id參數為1。
也可以將id一同輸入在網址裡,如:http://localhost:1234/movies/details?id=1

輸入的參數找到相對應的電影時,電影的Model會將資料傳遞給View

return View(movie);

檢視Views\Movies\Details.cshtml 

@model MyMVC.Models.Movie

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Title)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Genre)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Genre)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Price)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Price)
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
    @Html.ActionLink("Back to List", "Index")
</p>

View的最頂部可以看到@model的語句。當建立movie controller時,Visual Studio會自動在Details.cshtml 文件中加入@model的語句,指定model的對象。

@model MyMVC.Models.Movie

@model表示Controller使用強別傳遞資料給View,例如Details.cshtml裡顯示電影資料時使用的HTMLHelper方法DisplayNameFor 和 DisplayFor就是強別的類型。

Index.cshtml的View與MoviesController.cs文件裡的Index方法,可以看到Index方法要回傳View時,產生的List物件。

public ActionResult Index()
{
   return View(db.Movies.ToList());
}

Index.cshtml 裡,也可以看到 @model宣告於頂端

@model IEnumerable<MyMVC.Models.Movie>

這裡的@model定義了Controller會回傳一個強型別的list給View。Index.cshtml 使用foreach迴圈,將電影的資料以強型別顯示。

@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<MyMVC.Models.Movie>),迴圈裡的每個item都表示Movie裡的項目。
這樣的好處是,編譯時會進行偵錯,與在撰寫程式時,可以使用IntelliSense將項目點出。

 

SQL Server LocalDB

Entity Framework Code First 偵測到資料庫連線的Movies資料庫尚未建立,Code First 便會自動建立其資料庫。
可以在App_Data 文件裡面看到建立的資料庫,要是沒看到Movies.mdf 檔案,按下方案總管上方的顯示所有檔案,然後按下重新整理,就會看到App_Data資料夾裡多了Movies.mdf 檔案

在 Movies.mdf 檔案連點兩下開啟伺服器總管,展開資料表文件看到Movies資料表。
可以看到在ID旁邊有鑰匙圖案,在預設情況下,會將名為ID的屬性設為主鍵。

Movies資料表上按右鍵,選擇顯示資料表資料,看到所有建立的資料。

Movies資料表按下右鍵,選擇開啟資料表定義可以整個資料表的結構。

Entity Framework Code First 會根據先前建立的Movie Class 建立資料表架構。當完成時,在MovieDBContext 按右鍵選擇Close Connection 關閉連線(要是沒有關閉連線,會在下一次執行專案時發生錯誤)

現在,有了資料庫與顯示、編輯、更新、刪除資料的頁面。接下來,將更進一步研究當中的程式碼,與新增查詢的功能,來查詢資料庫裡的電影資料。

 

下一篇  Edit - 編輯的方法及View

 

 END 

回目錄