我們將重新建立 Controller,並且一次搞定 Controller/View/Model + Entuty Framework + 資料庫。
建立一個 Model類別
首先,在專案的 Models資料夾上,按下滑鼠右鍵,再選加入
再選類別
出現的選單,
只選 ASP.Net Core
和右邊選類別
名字輸入:movie.cs
產生的程式碼框架如下圖:
我們先填入下列內容:
namespace MvcMovie.Models
{
public class movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}
建立一個含 EF 的 Controller
在專案的 Controller資料夾上,按下滑鼠右鍵,
再選加入
再選控制器 (與前一篇文章不同,不是新增項目喔)
出現選單
再選控制器
右邊選使用 Entity Framework 執行檢視的控制器
會出現新增控制器的交談視窗
於模型類別,按下拉式選單,選 movie (mvcMovie.Models)
於資料內容類別,按下"+"的符號
然後按下新增
對於檢視部分,就保持預設的三個選項,都打勾。
對於控制器名稱,就保持預設的 moviesController
再按下新增
就會自動生成控制器類別(哇~程式碼有153行),還有五個檢視頁面:
這就是VS2017會自動幫你架好一個基本的 (create, read, update, and delete) 網頁框架(架手腳 scaffolding. ) 再來,我們要建立資料庫,將要使用 Entuty Framework 的 功能,它讓我們定義資料模型(data model),然後依據資料模型產生資料庫,維護資料庫。
程式碼雖然已經繩成,但是因為我們還沒有架設資料庫,所以直接執行,並到這新網頁: http://localhost:1234/movies/
會看到錯誤訊息:
專案增加 EF 工具
在方案總管,於專案MvcMovie 的上面按右鍵再選 編輯 MvcMovie.csproj.
檔案打開之後,檢查是否有下列兩行,在 <ItemGroup>標籤之中:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>
註:如果按照微軟英文教學做,到了這裡要自己加入。但是因為我們一開始就已經選擇了個人驗證機制,所以此處已經有了這兩行。
此時,我們專案中有關 movies的相關檔案資料夾如下:
使用 EF 工具建立資料庫
建立資料庫,我們打開 comand prompt, 並且移到專案的目錄(含有Startup.cs檔案之處)如果你也跟我一樣,有安裝 Power commands for Visual Studio,那麼在方案總管,
就可以直接點選進入!!
然後直下面的命令:
dotnet restoredotnet ef migrations add Initial -c mvcMovieContext
dotnet ef database update -c mvcMovieContext
下面是這三個步驟的執行結果截圖
- 執行 >dotnet restore
dotnet
(.NET Core) 是跨平台的.NET工具. 微軟的說明文件在 .dotnet restore
: 會依據 xxx .csproj 檔案裡面寫的定義,下載所使用的 NuGet 套件 - 執行 >dotnet ef migrations add Initial -c mvcMovieContext
這一步驟,是在執行 EF 的 migration 命令,使用 initial名字,產生一堆資料庫操作的類別程式碼, 所產生的檔案會在
/Migrations/<date-time>_Initial.cs
- 執行 >dotnet ef database update -c mvcMovieContext
然後上一次我們是讓網頁功能表的mvcMovie 連結到 MovieControl, 這次我們連結到 MoviesController. 打開 _Layout.cshtml檔案,修改這行:(原來的預設控制器指向 movie, 現在改為指向movies )
<a asp-area="" asp-controller="Movies" asp-action="Index" class="navbar-brand">MvcMovie</a>
執行它 Ctrl+F5,
然後按功能表上的 mvcMovie 地方:
可以再按 Creat New :
試著輸入資料:
回到 mvcMovie 那頁,已經有了一筆資料:
相依性注入Dependency Injection
打開檔案 Startup.cs並且觀察成員涵式
ConfigureServices
:當中一行淡藍色的碼,就是顯示 movie資料庫T被加入相依性注入的容器中.
再檢查檔案: Controllers/MoviesController.cs
並且觀察類別的建構子 constructor:
就是這個地方,連結了資料庫與控制器!
在檢視中使用模型內的資料
我們在之前的實作中,已知讓控制器傳資料給檢視的方法(利用 ViewDate)。那麼,如何讓模型裡的資料,也被檢視 view所存取? 微軟又提供了什麼ㄈ便設計環境?答案是:我們可先定義模型物件,然後再檢視的地方引用整個物件,而且在VS2017當中,可以自動顯示物件裡面的成員,幫便編輯程式碼。
譬如我們看
in the Controllers/MoviesController.cs file:
generated
Details
action method參數
id
會由網址傳遞過來,譬如:http://localhost:1234/movies/details/1
那麼它的動作是:
- 前半段網址,代表控制器是連結到
movies
controller - 第二段網址,則是代表指向的 action method 為
details
. - 最後 id= 1 +
傳遞參數
id
也可以在網址URL寫:再來,檢查檔案 Views/Movies/Details.cshtml
最上方的 @Model 就是用來指定,所要連結的模型 model !!!
再看 MoviesController當中,有個 method = Index()
其對應的 View = Index.cshtml
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewData["Title"] = "Index";
}<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@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>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
我們可以試著改變下圖的地方,可以看到VS2017會自動提示,有哪些籌元可選
本機 SQL資料庫
這個範例,現在是連結本機的 SQL資料庫。至於是電腦裡面哪一個資料庫? 由一個ConnectionString
指定,它是被定義在檔案: appsettings.json 打開這個檔案
我們可以看到有兩個 ConnectionString,
一個是代表我們的 Movie資料庫 (mvcMovieContext)
一個是代表基本帳號管理的 default connection資料庫
本機資料庫是輕量級的 SQL Server Express Database,再點腦裏面,就是一個副檔名為 *.mdf 的檔案,和一個同名但是附檔名為 .log, 兩個檔案組成。預設所建立的資料庫檔案,會在目錄:
C:/使用者/<user> 這個目錄裡面:
在 VS2017裡面,有工具可以看其內容:
按檢視
選 SQL Server物件總管
尋找到資料庫,資料表..
在 dbo.movie上面按右鍵
選檢視表設計工具
會出現視窗:
也可以檢視資料表的資料:
植入種子資料
在模型,增加一個類別 Seeddata 如下:using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new mvcMovieContext(
serviceProvider.GetRequiredService<DbContextOptions<mvcMovieContext>>()))
{
// Look for any movies.
if (context.movie.Any())
{
return; // DB has been seeded
}
context.movie.AddRange(
new movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Price = 7.99M
},
new movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
context.SaveChanges();
}
}
}
請注意, 程式碼裡面,名稱是有區分大小寫的,如果直接拷貝英文網站裡面的碼,由於 MvcMovieContext 不等於 mvcMovieContext ,所以編譯環境會找不到,會一直有紅色底線錯誤!!
重新建置(編譯)之後,執行時需要先刪除先前輸入的各筆資料,通通刪光之後,關掉瀏覽器,再一次執行 Ctrl+F5就可看到:
上面途中, ReleaseDate 顯示了日期和零點零分零秒的時間,較為難看;我們可以修改原始的movie.cs 變成如下的碼。請加上黃色底色的三行。
using System;using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;using System.Linq;using System.Threading.Tasks;namespace MvcMovie.Models
{
public class movie
{
public int ID { get; set; }
public string Title { get; set; } [Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}
在 VS2017中,環境還提供一格功能,就是可以去除沒有用的 Using
可以在程式碼中(譬如:movie.cs)任何空白處按右鍵:
執行移除並排序 Using之後變成:
建置後執行結果:
解說控制器與檢視的幾項聯繫
上述執行畫面,當我們鼠標停留在第四筆資料的 Edit的時候,其實,會看見瀏覽器將要傳遞的網址
這個網址是由 Views/Movies/Index.cshtml 檔案所產生的,因為程式碼中有下列,
其中第一行是產生 Edit的網址
第二行是產生 Detail的網址
第三行是產生 Delete的網址
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
在上述 Index畫面,瀏覽器裡選擇觀看原始檔時,將發現已經展開的 HTML:
這即是 ASP.Net Core MVC機制,在背後完成的工作。
以Edit為例子,
就是會跑到控制器為 movies,
Action method = Edit()
而且參數 id = 5
當我們仔細查看 moviesController.cs的程式,將會發現有兩個 Edit() !!
這是怎麼回事?
原來,
一個是當 HTTP Post的時候呼叫的,一個是 HTTP Get的時候呼叫的.
程式之中,是用方框刮起來的屬性來指定
因為預設屬性是 HTTP Get, 所以,一個省略屬性,第二個有寫[HttpPost]
另外,我們看到屬性
[ValidateAntiForgeryToken]
是做什麼用呢?它讓我們只寫上這一行屬性,就會自動引入程式碼來做輸入值得型別與值域的檢查,就像下面截圖:延伸的微軟閱讀資料
- Entity Framework Core
- EF Core supports many database engines.
- .NET Core command-line interface (CLI) tools
- Introduction to Dependency Injection in ASP.NET Core
沒有留言:
張貼留言