.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N170718501
出刊日期: 2017/7/12
本文將介紹如何在MVC 5的專案之中,整合Bootstrap的對話盒,設計資料新增功能,利用Entity Framework Code First技術自動建立資料庫,存取資料庫資料。如此不需要自己撰寫複雜的AJAX程式碼來更新網頁部分頁面。
建立範例專案
為了方便說明,我們先使用Visual Studio 2015來建立MVC 5的網站,從「File」-「New」-「Project」,在「New Project」對話盒中,確認視窗上方.NET Framework的目標版本為「.NET Framework 4.6」以上,選取左方「Installed」-「Templates」-「Visual C#」程式語言,從「Web」分類中,選取「ASP.NET Web Application(.NET Framework)」,適當設定專案名稱與專案存放路徑,按下「OK」鍵,請參考下圖所示:
圖 1:建立MVC 5專案。
在「New ASP.NET Web Application」對話盒中選取「MVC」,勾選下方的「MVC」項目,然後按一下畫面中的「OK」 按鈕,請參考下圖所示:
圖 2:勾選下方的「MVC」項目。
專案建立之後,可以從「Solution Explorer」視窗,檢視目前專案的結構,專案中會產生一個「Content」資料夾,裏頭存放Bootstrap套件相關的樣式表檔案,以及一個「Scripts」資料夾,其中存放jQuery與Bootstrap套件相關的JavaScript程式碼檔案,請參考下圖所示:
圖 3:範本專案的檔案結構。
更新Bootstrap版本到目前最新的3.3.7版,從Visual Studio 2015開發工具 -「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Manage Nuget Packages」,開啟對話盒,請參考下圖所示:
圖 4:使用Nuget Package Manager更新套件。
接著選取視窗上方的「Installed」選項,下方便會列出目前專案已安裝的套件,選取其中的bootstrap套件,在右方的下拉式清單方塊中,選取要使用的「3.3.7」版,然後按下「Update」按鈕進行更新,請參考下圖所示:
圖 5:更新套件到指定的版本。
Nuget工具會自動偵測套件的相依性,來安裝其它的相依套件,例如Bootstrap 3.3.7版要求相依的jQuery版本需要大於等於1.9.1版以上。
建立Employee模型
從Visual Studio 2015開發工具 -「Solution Explorer」- 專案 -「Models」目錄上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目,開啟「Add New Item」對話盒,請參考下圖所示:
圖 6:加入新項目。
在「Add New Item」對話盒選取「Class」項目,設定檔案名稱為「Employee.cs」,請參考下圖所示:
圖 7:加入Employee.cs檔案。
在Employee類別定義以下屬性,並設定Attribute,其中Name屬性的上方套用Required Attribute,並設定姓名空白時要顯示的自訂錯誤訊息:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace DialogDemo.Models
{
public class Employee
{
[Display(Name = "員工編號")]
public int Id { get; set; }
[Display(Name = "姓名")]
[Required(ErrorMessage = "姓名不可以為空白")]
[StringLength(200)]
public string Name { get; set; }
[Display(Name = "身高")]
public int Height { get; set; }
[Display(Name = "生日")]
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]
public DateTime BirthDate { get; set; }
[Display(Name = "婚姻狀態")]
public bool Married { get; set; }
}
}
建立ADO.NET實體資料模型
下一步是使用Visual Studio的功能來定義ADO.NET實體資料模型,然後利用Entity Framework Code First技術自動建立資料庫。在MVC的專案之中,通常將ADO.NET實體資料模型的相關程式置於Models資料夾之中。
從Visual Studio 2015開發工具 -「Solution Explorer」- 專案-「Models」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」,開啟「Add New Item」對話盒,請參考下圖所示:
圖 8:加入新項目。
在「Add New Item」對話盒選取「ADO.NET Entity Data Model」項目,設定名稱為「EmployeesContext」,請參考下圖所示:
圖 9:建立ADO.NET實體資料模型。
然後選取「Empty Code First model」項目,按下「Finish」按鈕,請參考下圖所示:
圖 10:選取「Empty Code First model」項目。
當精靈完成之後,接著Visual Studio就會自動在專案中Models資料夾內產生一個EmployeesContext.cs檔案,預設包含以下程式碼,為了簡單起見,底下列出的程式碼已經刪除程式碼註解部分的說明:
namespace DialogDemo.Models
{
using System;
using System.Data.Entity;
using System.Linq;
public class EmployeesContext : DbContext
{
public EmployeesContext()
: base("name=EmployeesContext")
{
}
}
}
此外這個步驟完成後,也會自動在專案根目錄下的web.config檔案中,設定資料庫連接字串,預設將資料庫建立在LocalDb之中):
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-DialogDemo-20170601035448.mdf;Initial Catalog=aspnet-DialogDemo-20170601035448;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="EmployeesContext" connectionString="data source=(LocalDb)\MSSQLLocalDB;initial catalog=DialogDemo.Models.EmployeesContext;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
修改EmployeesContext類別,為其加入一個Employees屬性,其型別是DbSet<Employee>:
namespace DialogDemo.Models
{
using System;
using System.Data.Entity;
using System.Linq;
public class EmployeesContext : DbContext
{
public EmployeesContext()
: base("name=EmployeesContext")
{
}
public DbSet<Employee> Employees { get; set; }
}
}
選Visual Studio開發工具 - 「Build」- 「Build Solution」項目,確認專案目前可以正確編譯。從Visual Studio開發工具的「Tools」-「Library Package Manager」-「Package Manager Console」開啟「Package Manager Console」視窗,然後在提示字元中輸入以下指令,利用ContextTypeName參數指定EmployeesContext類別的完整名稱,啟用Code First Migration功能:
Enable-Migrations -ContextTypeName DialogDemo.Models.EmployeesContext
得到的執行結果如下圖所示:
圖 11:圖 12:選取「Empty Code First model」項目。
修改程式碼如下,利用程式碼新增幾筆測試資料到資料庫資料表中:
namespace DialogDemo.Migrations
{
using Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<DialogDemo.Models.EmployeesContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(DialogDemo.Models.EmployeesContext context)
{
var employees = new List<Employee>{
new Employee {
Id = 1,
Name = "Mary",
Height = 160,
BirthDate = new DateTime(1951,1,3),
Married = false
},
new Employee {
Id = 2,
Name = "Candy",
Height = 160,
BirthDate = new DateTime(1945,3,4),
Married = true
},
new Employee {
Id = 3,
Name = "Judy",
Height = 172,
BirthDate = new DateTime(1978,8,3),
Married = true
},
new Employee {
Id = 4,
Name = "Bob",
Height = 184,
BirthDate = new DateTime(1951,11,3),
Married = false
},
new Employee {
Id = 5,
Name = "Jeffery",
Height = 158,
BirthDate = new DateTime(1964,5,23),
Married = false
},
new Employee {
Id = 6,
Name = "Sunny",
Height = 165,
BirthDate = new DateTime(1988,10,2),
Married = false
}
};
employees.ForEach(s => context.Employees.Add(s));
}
}
}
選Visual Studio開發工具 - 「Build」- 「Build Solution」項目,確認專案目前可以正確編譯。
在「Package Manager Console」視窗提示字元中輸入以下指令,建立資料庫:
Update-Database
執行結果,請參考下圖所示:
圖 13:建立資料庫。
完成此步驟之後,會根據組態檔的設定,建立資料庫。
設計控制器
從Visual Studio 2015開發工具-「Solution Explorer」視窗- 專案 -「Controllers」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「Controller」,開啟「Add Scaffold」對話盒,請參考下圖所示:
在「Add Scaffold」對話盒中選取「MVC 5 Controller with views, using Entity Framework」項目,然後按下「Add 」按鈕,請參考下圖所示:
圖 15:新增「MVC 5 Controller with views, using Entity Framework」項目。
在「Add Controller」對話盒設定以下項目:
- a. Model class:選取「Employee」類別。
- b. Data context class選取:「EmployeesContext」。
- c. 勾選「Generate views」核取方塊。
- d. 勾選「Reference script libraries」核取方塊。
- e. 勾選「Use a layout page:」核取方塊。
- f. 設定Controller名稱:「EmployeesController」。
請參考下圖所示:
圖 16:新增控制器。
然後按下「Add」按鈕。Visual Studio 2015便會在「Views\Employees」資料夾下,新增檢視檔案,以及在「Controllers」資料夾下,新增EmployeesController.cs,包含控制器程式碼。
選取Visual Studio開發工具,「Build」-「Build Solution」編譯目前的專案,確認程式碼能正確編譯。
從「Solution Explorer」視窗- 選取Views\Employees資料夾下的Index.cshtml 檔案,按CTRL+F5執行Index檢視,現在你可以使用工具產生出的程式碼編修資料,請參考下圖所示:
圖 17:查詢資料表資料。
目前若點選「Create」超連結,會跳到另一個畫面輸入資料,請參考下圖所示:
圖 18:新增資料表資料。
設計資料新增功能
接著我們將改用Bootstrap對話盒來設計資料新增功能。首先改寫Controllers\EmployeesController.cs檔案中的EmployeesController類別,新增兩個「_Create」方法,方法的名稱故意以「_」開始和Visuaul Studio工具產生的「Create」方法有所區別。這兩個「_Create」方法叫用PartialView()方法,回傳部分檢視的內容。此外我們不希望使用者直接在瀏覽器直接輸入URL:「http://localhost /Employees/_Create」來叫用此方法,所以Create方法上方套用了[ChildActionOnly] Attribute:
[ChildActionOnly]
public ActionResult _Create() {
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _Create([Bind(Include = "Id,Name,Height,BirthDate,Married")] Employee employee) {
if (ModelState.IsValid) {
db.Employees.Add(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
return PartialView(employee);
}
建立_Create.cshtml檔案,從「Solution Explorer」視窗「Views\Employees」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」選項,選取「View 」,請參考下圖所示:
圖 19:加入_Create檢視。
在下一個畫面,將檔案名稱設定為「_Create.cshtml」,其它項目保留預設設定,然後按下「Add」按鈕,,請參考下圖所示:
圖 20:建立_Create 檢視。
下一步驟是修改新建立的Views\Employees\_Create.cshtml檔案,套用Bootstrap的對話盒與標籤:
@model DialogDemo.Models.Employee
@{
ViewBag.Title = "Create";
}
<!-- Modal -->
@using (Html.BeginForm("_Create", "Employees")) {
@Html.AntiForgeryToken()
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header modal-header-primary">
<button type="button" class="close" aria-label="Close" data-dismiss="modal">×</button>
<h4 class="modal-title">Employee新增</h4>
</div>
<div class="modal-body">
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Height, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Height, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Height, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BirthDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BirthDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BirthDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Married, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Married)
@Html.ValidationMessageFor(model => model.Married, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer modal-footer-primary">
<button type="submit" class="btn btn-default">Create</button>
</div>
</div>
</div>
</div>
}
修改Views\Employees\Index.cshtml檔案,在檔案最下方,加入以下程式碼,利用Html.Action插入
@model IEnumerable<DialogDemo.Models.Employee>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Height)
</th>
<th>
@Html.DisplayNameFor(model => model.BirthDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Married)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Height)
</td>
<td>
@Html.DisplayFor(modelItem => item.BirthDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Married)
</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>
}
</table>
<p>
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">新增</button>
</p>
@Html.Action("_Create")
資料新增時,需要利用jQuery Validation Plugin來進行資料驗證,現在新增的畫面內嵌在Index檢視之中,Index檢視又套用_Layout檔案,所以我們接著修改Views\Shared\_Layout.cshtml檔案,在「Scripts.Render("~/bundles/jquery")」這行程式碼下一行,引用jQuery Validation:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
這樣所有的步驟就完成了,選取Visual Studio 「Build」-「Build Solution」編譯目前的專案,確認程式碼能正確編譯。從「Solution Explorer」視窗- 選取Views\Employees資料夾下的Index.cshtml 檔案,按CTRL+F5執行Index檢視,現在你可以使用工具產生出的程式碼編修資料,請參考下圖所示:
圖 21:範例測試。
當你點選畫面中的「新增」按鈕,就會看到一個空白的新增表單,以對話盒方式呈現,請參考下圖所示:
圖 22:新增資料測試
若輸入正確資料按下畫面中的「Create」按鈕,資料將寫回資料庫,Index檢視也會馬上呈現新增的資料,請參考下圖所示:
圖 23:資料成功新增,回到Index檢視。
若資料輸入有誤,則利用jQuery Validation進行驗證,並顯示錯誤的訊息,請參考下圖所示:
圖 24:資料有誤,顯示錯誤訊息。
在_Layout檔案加上CSS自訂Bootstrap對話盒的表頭與表尾樣式:
<style>
.modal-header-primary {
color: #fff;
padding: 9px 15px;
border-bottom: 1px solid #eee;
background-color: #428bca;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.modal-footer-primary {
color: #fff;
padding: 9px 15px;
border-top: 1px solid #eee;
background-color: #428bca;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
</style>
套用樣式的執行結果,請參考下圖所示:
圖 25:自訂Bootstrap對話盒的表頭與表尾樣式。