ASP.NET Core MVC 和 Visual Studio入門(四)新增模型

俱會一處發表於2017-06-13

ASP.NET Core MVC 和 Visual Studio入門(四)新增模型

 

Rick AndersonTom Dykstra

 

在要節中將新增一些在資料庫中管理電影的類,這些類將成為MVC應用的“Model(模型)”部分。

這些類將與EntityFramework Core (EF Core)一起用於運算元據庫,EF Core是可以簡化那些不得不寫的訪問資料庫的程式碼的物件關係對映(ORM)框架,本教程將使用SQLite,但EF Core支援許多資料庫引擎

將建立的模型類被稱作POCO類(來自“plain-old CLR objects”),因為它們不依賴於EF Core,它們只是定義了將被儲存在資料庫中的資料的所有屬性。

在這個教程中,將首先寫模型類,接著EF Core將會建立資料庫,另一種這沒有討論的方法可根據已經存在的資料庫生成模型類,要了解這個方法的相關資訊,請看ASP.NET Core - Existing Database.

 

1.新增資料模擬類

在解決方案瀏覽器中,右擊MvcMovie 專案 >Add > New Folder,命名資料夾為 Models.

在解決方案瀏覽器中,右擊所建的Models資料夾> Add > Class,命名類為Movie,新增如下的屬性:

using System;

 

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; }

    }

}

ID欄位是資料庫所需要的,要用來作為主鍵。

生成專案以核實你沒有任何錯誤而且已經為本MVC應用新增了一個模型。

2.搭建一個控制器

在解決方案瀏覽器中,右擊 Controllers 資料夾 > Add > Controller


 

Add  MVC Dependencies 對話方塊中, 選擇 MinimalDependencies, 再選擇Add

 

Visual Studio 新增了搭建控制器所需的依賴項,但是控制器本身沒有被建立,下一個> Add > Controller的呼叫才會建立控制器。

在解決方案瀏覽器中,右擊Controller資料夾>Add>Controller,



Add Scaffold 對話方塊中, 點選 MVC Controller with views, usingEntity Framework > Add.



  •  完成Add Controller 對話方塊:
  • Model class: Movie (MvcMovie.Models)
  • Data context class: 選擇“ +” 圖示並新增預設的MvcMovie.Models.MvcMovieContext

 

 

  • Views: 保持每一個被勾選的選項的預設值。
  • Controller name: 保持預設的MoviesController
  • 點選 Add

 

 

系統自動生成了電影控制器(Controllers/MoviesController.cs)以及建立、刪除、詳情、編輯、索引等網頁的Razor 檢視檔案。

CRUD (create, read, update, and delete)的行為方法和檢視自動建立被稱為搭建(scaffolding),這使我們很快就有了一個能管理一個電影資料庫的全功能網頁應用。

如果執行應用並點選Mvc Movie連結,將會得到一個類似下面所示的錯誤:

An unhandled exception occurredwhile processing the request.

SqlException: Cannot opendatabase "MvcMovieContext-<GUID removed>"

requested by the login. The loginfailed.

Login failed for user Rick

 

大意為:

處理這個需求時,發生了未處理的異常。

SqlException: 不能開啟登入所需的"MvcMovieContext-<GUIDremoved>" 資料庫,登入失敗,使用者Rick登入失敗。

這時,我們需要建立這個資料庫,我們將使用EF Core 遷移 功能來完成這個工作,遷移允許建立匹配資料模型的資料庫並在資料模型改變時更新資料庫。

 

3.為遷移新增EF加工

  • In Solution Explorer, right click the MvcMovie project > Edit MvcMovie.csproj.
  • 在解決方案瀏覽器,右擊MvcMovie 專案 > Edit MvcMovie.csproj.

 

  • 新增 "Microsoft.EntityFrameworkCore.Tools.DotNet" NuGet 包:

 

XML

<ItemGroup>

 <DotNetCliToolReferenceInclude="Microsoft.VisualStudio.Web.CodeGeneration.Tools"Version="1.0.0" />

 <DotNetCliToolReferenceInclude="Microsoft.EntityFrameworkCore.Tools.DotNet"Version="1.0.0" />

</ItemGroup>

 

注意:上面顯示的版本號在寫作時是正確的。

儲存修改。

4.新增初始遷移並更新資料庫

  • 航到本專案目錄(該目錄包括Startup.cs檔案)
  • 在命令提示符下執行以下命令:

       dotnet restore

       dotnet ef migrations add Initial

       dotnet ef database update

 

  • dotnet (.NET Core)是.NET的跨平臺實現,可在閱讀相關知識.
  • dotnet restore :該命令下載在.csproj檔案中指定的NuGet包.
  • dotnet ef migrations add Initial:該命令執行Entity Framework .NET Core CLI遷移命令並建立初始遷移。“add”後面的引數是指定給該遷移的命名,由於本命令是初始的資料庫遷移,所以命名該遷移為“Initial(初始的)”。這個操作建立了包含要新增 Movie表到資料庫的遷移命令的Data/Migrations/<date-time>_Initial.cs檔案。
  • dotnet ef database update:該命令用剛剛建立的遷移更新資料庫。

我們將在下個教程中學習資料庫和連線字串,你可以在新增欄位教程中學習有關資料模型的變更。

5.Test the app測試應用

  • 執行應用並點選MvcMoview連結。
  • 點選Create New連結並建立一部電影。

你可能會無法在價格欄位中輸入小數點或逗號,要使使用逗號“,”作為小數點和使用非美國英語日期格式的非英語場合支援jQuery 驗證,必須採取措施來全球化應用,更多資訊見附加資源,現在,只需要輸入整數如10。

在一些場合下你會需要指定資料格式,見下面的高亮(加粗)程式碼。

 

using System;

usingSystem.ComponentModel.DataAnnotations;

 

namespace MvcMovie.Models

{

    public class Movie

    {

        public int ID { get; set; }

        public string Title { get; set; }

        [DisplayFormat(DataFormatString ="{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

        public DateTimeReleaseDate { get; set; }

        public string Genre { get; set; }

        public decimal Price { get; set; }

    }

}

我們將的後面的教程中討論DataAnnotations。

點選Create引發表單被提交給伺服器,在那兒電影資訊被儲存在資料庫中,再重定位到/Movies URL,可以在列表中看到最新建立的電影。


多建立幾個電影條目,嘗試Edit, Details, 和 Delete 等這些全功能連結。

6.Dependency Injection依賴項注入

開啟Startup.cs檔案並檢查ConfigureServices:

 

public void ConfigureServices(IServiceCollectionservices)

{

    // Addframework services.

    services.AddMvc();

 

    services.AddDbContext<MvcMovieContext>(options=>

上面高亮(粗體)顯示的程式碼展示了電影資料庫上下文被加入到依賴項注入容器中,跟隨在services.AddDbContext<MvcMovieContext>(options=>

後面的行沒有顯示出來(見你的程式碼),它指定了要使用的資料庫和連線字串。=>是lambda 操作符.

開啟Controllers/MoviesController.cs檔案並檢查其構造器:

public class MoviesController : Controller

{

    private readonlyMvcMovieContext _context;

 

    publicMoviesController(MvcMovieContext context)

    {

        _context = context;

    }

該構造器使用依賴項注入把資料庫上下文(MvcMovieContext)注入到控制器中,資料庫上下文在控制器中每個的CRUD方法內被使用。

7.Strongly typed models and the @model keyword強型別方法和@model關鍵字

在本教程的前面,我們見過控制器如何使用ViewData字典傳遞資料或物件給檢視,ViewData字典是提供方便的後期繫結方法以傳遞資訊給檢視的動態物件。MVC也提供了向檢視傳遞強型別模型物件的能力,這種強型別方法可提供更好的程式碼編譯時間檢查和更深的智慧感知。基架機制在建立方法和檢視時使用了這種方法(即,傳遞強型別模型)和MoviesController類以及檢視。

在Controllers/MoviesController.cs檔案中檢查產生的Details方法:

 

// GET: Movies/Details/5

public async Task<IActionResult> Details(int? id)

{

    if (id == null)

    {

        returnNotFound();

    }

    var movie = await_context.Movie

        .SingleOrDefaultAsync(m => m.ID ==id);

    if (movie == null)

    {

        returnNotFound();

    }

 

    return View(movie);

}

這個id引數通常作為路由資料被傳遞,比如http://localhost:5000/movies/details/1使:

  • 控制器為電影(movies)控制器(第一URL段)。
  • 行為為詳情(details)(第二URL段)。
  •  id為1(最後的URL段)

你也可能用如下的查詢字串傳值給id:

http://localhost:1234/movies/details?id=1

當電影被找到,電影模型的例項被傳遞給Details檢視:

C#

return View(movie);

檢查Views/Movies/Details.cshtml檔案的內容:

@model MvcMovie.Models.Movie

@{

    ViewData["Title"] ="Details";

}

<h2>Details</h2>

<div>

    <h4>Movie</h4>

    <hr/>

    <dlclass="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>

<div>

    <aasp-action="Edit" asp-route-id="@Model.ID">Edit</a> |

    <aasp-action="Index">Back to List</a>

</div>

通過在檢視檔案的頂部包含一個@model語句,可以指定檢視期望的物件型別。當建立該電影控制器時,VisualStudio自動在Details.cshtml檔案的頂部包含了下面的@mode語句。

HTML

@model MvcMovie.Models.Movie

這個@model指令允許訪問控制器通過使用強型別的模型物件傳給檢視的電影,比如,在Details.cshtml檢視中,程式碼將每個電影欄位用強型別模型物件傳遞給DisplayNameFor 和 DisplayFor輔助工具。Create(建立)和Edit(修改)方法和檢視也傳遞Movie模型物件。

在Movies控制器中檢查Index.cshtml檢視和Index方法,注意當程式碼呼叫View方法時,如何建立一個列表(List)物件, 程式碼將這個Movies列表從Index行為方法傳遞給檢視。

// GET: Movies

public async Task<IActionResult> Index()

{

    return View(await_context.Movie.ToListAsync());

}

當建立該電影控制器,基架自動在Index.cshtml檔案的頂部包含了下列@model語句。

@model IEnumerable<MvcMovie.Models.Movie>

@model指令允許訪問控制器通過使用強型別的模型物件傳遞給檢視的電影列表 ,比如,在Index.cshtml檢視中,程式碼使用一個foreach語句在強型別模型物件上遍歷電影列表的資訊。

 

 

@model IEnumerable<MvcMovie.Models.Movie>

 

@{

    ViewData["Title"] ="Index";

}

 

<h2>Index</h2>

 

<p>

    <aasp-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>

因為該模型物件是強型別(如IEnumerable<Movie>物件),迴圈中的每一項被顯示為電影。在其他的好處中,你還獲得了程式碼編譯時檢查和在程式碼編輯中的全智慧感知支援:

 

 

8.附加的資源

 

 

原文

 

相關文章