使用MVC整合Bootstrap對話盒新增資料 - 1

by vivid 12. 七月 2017 11:27

.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」鍵,請參考下圖所示:

clip_image002

圖 1:建立MVC 5專案。

在「New ASP.NET Web Application」對話盒中選取「MVC」,勾選下方的「MVC」項目,然後按一下畫面中的「OK」 按鈕,請參考下圖所示:

clip_image004

圖 2:勾選下方的「MVC」項目。

專案建立之後,可以從「Solution Explorer」視窗,檢視目前專案的結構,專案中會產生一個「Content」資料夾,裏頭存放Bootstrap套件相關的樣式表檔案,以及一個「Scripts」資料夾,其中存放jQuery與Bootstrap套件相關的JavaScript程式碼檔案,請參考下圖所示:

clip_image006

圖 3:範本專案的檔案結構。

更新Bootstrap版本到目前最新的3.3.7版,從Visual Studio 2015開發工具 -「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Manage Nuget Packages」,開啟對話盒,請參考下圖所示:

clip_image008

圖 4:使用Nuget Package Manager更新套件。

接著選取視窗上方的「Installed」選項,下方便會列出目前專案已安裝的套件,選取其中的bootstrap套件,在右方的下拉式清單方塊中,選取要使用的「3.3.7」版,然後按下「Update」按鈕進行更新,請參考下圖所示:

clip_image010

圖 5:更新套件到指定的版本。

Nuget工具會自動偵測套件的相依性,來安裝其它的相依套件,例如Bootstrap 3.3.7版要求相依的jQuery版本需要大於等於1.9.1版以上。

 

建立Employee模型

從Visual Studio 2015開發工具 -「Solution Explorer」- 專案 -「Models」目錄上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目,開啟「Add New Item」對話盒,請參考下圖所示:

clip_image012

圖 6:加入新項目。

在「Add New Item」對話盒選取「Class」項目,設定檔案名稱為「Employee.cs」,請參考下圖所示:

clip_image014

圖 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」對話盒,請參考下圖所示:

clip_image015

圖 8:加入新項目。

在「Add New Item」對話盒選取「ADO.NET Entity Data Model」項目,設定名稱為「EmployeesContext」,請參考下圖所示:

clip_image017

圖 9:建立ADO.NET實體資料模型。

然後選取「Empty Code First model」項目,按下「Finish」按鈕,請參考下圖所示:

clip_image019

圖 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

得到的執行結果如下圖所示:

clip_image021

圖 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

執行結果,請參考下圖所示:

clip_image023

圖 13:建立資料庫。

完成此步驟之後,會根據組態檔的設定,建立資料庫。

設計控制器

從Visual Studio 2015開發工具-「Solution Explorer」視窗- 專案 -「Controllers」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「Controller」,開啟「Add Scaffold」對話盒,請參考下圖所示:

clip_image025圖 14:新增控制器。

在「Add Scaffold」對話盒中選取「MVC 5 Controller with views, using Entity Framework」項目,然後按下「Add 」按鈕,請參考下圖所示:

clip_image027

圖 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」。

請參考下圖所示:

clip_image029

圖 16:新增控制器。

然後按下「Add」按鈕。Visual Studio 2015便會在「Views\Employees」資料夾下,新增檢視檔案,以及在「Controllers」資料夾下,新增EmployeesController.cs,包含控制器程式碼。

選取Visual Studio開發工具,「Build」-「Build Solution」編譯目前的專案,確認程式碼能正確編譯。

從「Solution Explorer」視窗- 選取Views\Employees資料夾下的Index.cshtml 檔案,按CTRL+F5執行Index檢視,現在你可以使用工具產生出的程式碼編修資料,請參考下圖所示:

clip_image031

圖 17:查詢資料表資料。

目前若點選「Create」超連結,會跳到另一個畫面輸入資料,請參考下圖所示:

clip_image033

圖 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 」,請參考下圖所示:

clip_image035

圖 19:加入_Create檢視。

在下一個畫面,將檔案名稱設定為「_Create.cshtml」,其它項目保留預設設定,然後按下「Add」按鈕,,請參考下圖所示:

clip_image037

圖 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">&times;</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>&copy; @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檢視,現在你可以使用工具產生出的程式碼編修資料,請參考下圖所示:

clip_image039

圖 21:範例測試。

當你點選畫面中的「新增」按鈕,就會看到一個空白的新增表單,以對話盒方式呈現,請參考下圖所示:

clip_image041

圖 22:新增資料測試

若輸入正確資料按下畫面中的「Create」按鈕,資料將寫回資料庫,Index檢視也會馬上呈現新增的資料,請參考下圖所示:

clip_image043

圖 23:資料成功新增,回到Index檢視。

若資料輸入有誤,則利用jQuery Validation進行驗證,並顯示錯誤的訊息,請參考下圖所示:

clip_image045

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

 

套用樣式的執行結果,請參考下圖所示:

clip_image047

圖 25:自訂Bootstrap對話盒的表頭與表尾樣式。

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List