【第一篇】ASP.NET MVC快速入門之數據庫操做(MVC5+EF6)

目錄

【第一篇】ASP.NET MVC快速入門之數據庫操做(MVC5+EF6)php

【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6)css

【第三篇】ASP.NET MVC快速入門之安全策略(MVC5+EF6)html

【第四篇】ASP.NET MVC快速入門之完整示例(MVC5+EF6)前端

【番外篇】ASP.NET MVC快速入門之免費jQuery控件庫(MVC5+EF6)jquery

 

請關注三石的博客:http://cnblogs.com/sanshi數據庫

 

新建項目

打開VS2015,找到菜單項[文件->新建->項目],打開向導對話框:bootstrap

注意咱們的選擇項:瀏覽器

1.     運行平臺:.NET FrameWork 4.5安全

2.     項目模板:ASP.NET Web Application (.NET Framework)app

3.     項目名稱:AspNetMvc.QuickStart,若是你在跟着本教程練習,建議起相同的項目名稱,方便直接拷貝代碼到你的項目中。

 

點擊[肯定]按鈕,嚮導會帶咱們到另外一個選擇對話框:

 

 

因爲本教程是快速入門,因此咱們從最簡單的入手,只勾選必需的選項:

1.     不進行身份驗證。ASP.NET MVC提供了完善的身份驗證方案,咱們會有單獨的文章講解。

2.     僅勾選 MVC 引用。

 

點擊[肯定]VS2015會建立一個可直接運行的項目,按下快捷鍵[Ctrl+F5],不調試直接運行:

 

 

默認的目錄結構以下:

 

若是你以前在WebForms下進行開發,對其中的一些文件夾和文件應該很熟悉了:

1.     Web.config:項目配置文件,裏面保存項目配置參數以及數據庫鏈接字符串。

2.     packages.configNuget配置文件

3.     Global.asax:全局代碼文件,提供應用程序級別以及會話級別的事件處理函數,能夠在Application_Start中註冊全局變量。

4.     favicon.ico:瀏覽器地址欄圖標,在HTMLhead標籤中引用。

5.     App_Data:放置本地數據庫文件,好比LocalDB生成的數據庫文件。

 

下面幾個文件夾,用來放置靜態文件,從名稱就能夠方便的猜出其用途:

1.     Scripts:放置靜態腳本文件,好比jQuery等。

2.     fonts:放置圖標字體文件,好比流行的FontAwesome字體等。

3.     Content:放置靜態文件,好比xml文件、BootstrapCSS庫。

 

下面幾個文件是ASP.NET MVC新引入的:

1.     App_Start:用來放置應用初始化類,這個是MVC4引入的一個命名約定,其實這就是一個普通的文件夾,沒有特殊的含義。

2.     Controllers:控制器類。

3.     Models:模型類,好比EF CodeFirst的模型定義。

4.     Views:視圖文件,最初的視圖引擎是WebForms View Engine,使用和ASPX文件相同的語法,而如今用的Razor視圖引擎是MVC3引入的,以cshtml爲後綴。

 

 

頁面流程

首先看下 [About]頁面:

 

這個頁面之因此可以呈如今咱們眼前,經歷了三個主要流程:

1.     MVC的路由引擎根據URL查找相應的控制器(HomeController.cs)。

2.     控制器的操做方法About準備數據,而後傳入視圖Home/About.cshtml

3.     視圖準備HTML片斷,放入佈局頁面並返回瀏覽器。

 

路由引擎->控制器

一切還得從Global.asax中提及,在其中的應用程序啓用事件中,咱們須要註冊路由處理器:

protected void Application_Start()
{
       AreaRegistration.RegisterAllAreas();
       FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
       RouteConfig.RegisterRoutes(RouteTable.Routes);
       BundleConfig.RegisterBundles(BundleTable.Bundles);
}

 

RouteConfig.cs類位於App_Start文件夾中,咱們來看下內容:

public class RouteConfig
{
       public static void RegisterRoutes(RouteCollection routes)
       {
              routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
              routes.MapRoute(
                     name: "Default",
                     url: "{controller}/{action}/{id}",
                     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
              );
       }
}

 

 

這裏註冊一個名爲Default的路由規則,對應的URL{controller}/{action}/{id},這裏三個佔位符分別表示:

1.     {controller}:控制器,默認是Home,對應的控制器類是HomeController.cs

2.     {action}:控制器裏面的方法,默認是Index。因此若是用戶直接經過http://localhost/訪問系統時,默認調用Home控制器中的Index方法處理。

3.     {id}:參數ID,可選項,這個參數對應於操做方法中的id參數。

 

控制器方法->視圖

經過上面的介紹,咱們就知道了http://localhost:55654/Home/About網址對應於Home控制器的About方法。

 

咱們在Controllers/HomeController.cs中找到相應的方法:

public ActionResult About()
{
       ViewBag.Message = "Your application description page.";
 
       return View();
}

 

 

ViewBag是一個動態對象(dynamic),能夠用來存儲任意參數,用來從控制器向視圖傳遞數據。

 

從控制器向視圖傳遞數據通常有兩種方法:

1.     傳入模型,而後在視圖中經過Model對象訪問,這是一種強類型的方式,也是推薦的作法。其侷限性就是隻能傳入一個模型,若是須要傳入多個模型對象,就須要自定義類來包含多個模型,另外一種方法就是ViewBag

2.     ViewBag,視圖包傳遞數據很是方便,可是在視圖中可能須要進行強制類型轉換。在常見的傳入一個主模型和多個次模型時,能夠把屢次模型放到ViewBag中,從而避免自定義類的麻煩。

 

做爲命名約定,這個操做方法會自動調用相應名稱的視圖文件About.cshtml

視圖->瀏覽器

下面來看About.cshtml視圖文件:

@{
    ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
 
<p>Use this area to provide additional information.</p>

 

 

@開頭用來輸出C#代碼的運行結果,MVC會自動判斷於何處結束C#代碼,並轉入HTML代碼。

 

須要注意,頁面第一行的@{ }用來執行一段C#代碼,不會輸出內容,這裏定義了一個ViewBag.Title的變量,並在下面的代碼中使用@ViewBag.Title輸出到頁面中。

 

不少初學者可能有些疑惑,爲啥控制器中定義了ViewBag.Message,而在視圖中定義了ViewBag.Title,這二者有啥區別?

通常來講是沒有功能的區別,僅僅是語義的區別。在視圖中定義的變量僅在視圖中使用,好比這裏定義的ViewBag.Title不只在About.cshtml中使用,並且在佈局視圖Shared/­_Layout.cshtml中也用到了。

 

佈局視圖

佈局視圖相似於WebForms中的母版頁,具體的視圖頁面會做爲一部分嵌入到佈局視圖中,而後返回到瀏覽器造成一個完整的頁面。

 

每個視圖頁面默認會使用Views/_ViewStart.cshtml中的定義的內容:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

 

 

這裏面指定了佈局視圖的位置,咱們來簡單看下佈局視圖的內容:

<!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>
            </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/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

 

 

其中head標籤下面的title中使用了在About視圖中定義的ViewBag.Title屬性。

這個佈局視圖使用Bootstrap庫定義的CSS樣式來完成,包含標題欄,導航菜單,以及頁腳的定義,具體的內容會嵌入@RenderBody()的地方,最終造成完整的HTML頁面返回。

 

數據庫操做

上面從控制器傳入視圖的數據是硬編碼的一個字符串,實際項目中則常常須要從數據庫中讀取數據,咱們使用微軟推薦的Entity Framework CodeFirst開發模式來建立和使用數據庫。

安裝Entity Framework

首先須要安裝EF,在VS2015中找到[工具]菜單,而後找到NuGet包管理器:

 

轉到[瀏覽]選項卡,能夠搜索Entity Framework,安裝其最新穩定版到項目中:

 

安裝後,會自動更改Web.config添加相應的配置信息。

 

 

建立模型

咱們計劃完成一個簡單的學生管理系統,包含基本的增刪改查(CRUD)。

首先在Models文件,建立學生(Student)的模型類:

public class Student
{
       public int ID { get; set; }
       public string Name { get; set; }
       public int Gender { get; set; }
       public string Major { get; set; }
       public DateTime EntranceDate { get; set; }
}

 

 

而後建立數據庫操做上下文,EF須要這個文件來建立和訪問數據庫:

public class StudentDbContext : DbContext
{
       public DbSet<Student> Students { get; set; }
}

 

 

因爲這個類繼承自EFDbContext基類,所以須要在文件頭部添加以下引用:

using System.Data.Entity;

 

 

 

建立完這兩個文件,須要從新編譯項目(快捷鍵Ctrl+Shift+B),不然下面添加控制器時會出錯。

添加控制器

Controllers目錄上點擊右鍵,添加控制器,彈出嚮導對話框:

 

這裏選擇 MVC 5 Controller with views, using Entity Framework,而後進入設置對話框:

在這個對話框中,咱們須要指定剛纔建立的模型類(Student)和數據訪問上下文類(StudentDbContext),而後VS不只能夠自動建立視圖,並且使用EF自動建立CRUD的所有代碼,是否是很酷!

 

所有功能完成了!

是否是很驚奇,咱們甚至沒來得及寫視圖代碼,沒有配置數據庫,沒有寫CRUD的邏輯代碼,VS模板幫咱們生成了一切,如今運行一下(Ctrl+F5),並在瀏覽器中輸入/Students

 

表格頁面

表格頁面對應於Students控制器下的Index操做方法:

public class StudentsController : Controller
{
       private StudentDbContext db = new StudentDbContext();
 
       // GET: Students
       public ActionResult Index()
       {
              return View(db.Students.ToList());
       }
      
}

 

 

首先,咱們看到控制器內部定義了一個私有變量db,並進行初始化。這是數據庫操做上下文實例,全部的CRUD操做都講依賴於這個實例。

 

Index方法中,經過向View方法傳遞學生列表的方式,把模型數據傳遞到了視圖,在Views/Students/Index.cshtml視圖文件中,咱們聲明瞭傳入模型的類型:

@model IEnumerable<AspNetMvc.QuickStart.Models.Student>

 

 

在視圖中,Model屬性的類型就肯定爲強類型IEnumrable<Student>,配合VS提供的智能感知,不只能夠快速編寫代碼,而且在編譯時還檢查代碼的有效性。

完整的Index.cshtml代碼:

@model IEnumerable<AspNetMvc.QuickStart.Models.Student>
 
@{
    ViewBag.Title = "Index";
}
 
<h2>Index</h2>
 
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Gender)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Major)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.EntranceDate)
        </th>
        <th></th>
    </tr>
 
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Gender)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Major)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EntranceDate)
        </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>

 

 

看着頗有古老的ASP的感受吧,不過這裏的Model屬性是強類型的,所以在foreach循環中,VS明確知道item類型是Student,從而方便代碼編寫:

 

@Html裏面都是MVC提供的輔助方法,用來輔助生成HTML代碼:

1.     ActionLink:用來生成超連接,連接到本控制器內的某個操做方法(也能夠是其餘控制器的方法,有重載函數),能夠指定路由參數,經過對象初始化語法來建立,好比new {id=item.ID}

2.     DisplayNameFor:顯示模型屬性的名稱。強類型輔助方法,容許咱們使用一個lambda表達式來指定某個模型屬性,而不用寫字符串。好處不只有智能感知,編譯時檢查,並且也方便代碼重構,好比咱們在更改模型的屬性名稱時,視圖中的相應代碼也會改變。

3.     DisplayFor:顯示模型屬性的值。

新增頁面

 

新增頁面對應於Students控制器下的Create操做方法:

// GET: Students/Create
public ActionResult Create()
{
       return View();
}

 

 

對應的視圖文件:

@model AspNetMvc.QuickStart.Models.Student
 
@{
    ViewBag.Title = "Create";
}
 
<h2>Create</h2>
 
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
   
    <div class="form-horizontal">
        <h4>Student</h4>
        <hr />
        @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>
             
              @* 省略 Gender Major EntranceDate *@
       
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}
 
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

 

首先定義了視圖中使用的模型類型是Student,這樣LabelFor強類型輔助方法就能夠從模型元數據中獲取須要顯示的文本。

 

頁面打開時,因爲並未傳入任何模型對象,因此Model爲空對象,以下所示:

因此頁面上默認的輸入框都是空的,截圖中是做者輸入值後的效果。

 

Html.BeginForm()會在頁面上生成一個form標籤,默認的提交地址仍是當前頁面(action=/Students/Create),默認的請求方法是post,以下所示:

 

所以,點擊[Create]按鈕時,會發出一個POST請求到後臺,對應於Students控制器的Create方法。

保存數據與模型綁定

下面咱們來看下擁有[HttpPost]元數據的Create方法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Gender,Major,EntranceDate")] Student student)
{
       if (ModelState.IsValid)
       {
              db.Students.Add(student);
              db.SaveChanges();
              return RedirectToAction("Index");
       }
 
       return View(student);
}

 

 

這裏面有兩個安全措施:

1.     ValidateAntiForgeryToken:用來阻止CSRF(跨站請求僞造)。

2.     Bind:用來阻止Over-Posting(過多提交攻擊)。

這兩個安全手段咱們會在之後的文章中詳細介紹,這裏就先略過。

 

咱們先看下本次請求的POST參數:

 

可是Create方法中只有一個Student對象參數,是否是很神奇,其實這是一個重要的概念模型綁定

 

若是在WebForms中,咱們能夠會寫一堆代碼來從Request.Form中獲取參數,並重建Student對象,相似以下代碼:

Student student = new Student();
student.Name = Request.Form["Name"];
student.Gender = Convert.ToInt32(Request.Form["Gender"]);
....

 

 

MVC中,這一過程是自動完成,簡單來講這就是模型綁定。

 

可是實際的模型綁定過程,不只在請求的表單數據中查找,還會在路由參數,URL查詢字符串,以及Cookie中查找。

 

若是模型綁定失敗(好比模型參數不符合驗證規則),則ModelState.IsValid就爲false,這時會直接返回頁面內容,此時模型對象student中保存的是用戶輸入的值,前端也會有錯誤提示,這個過程咱們會在下一篇文章中講解。

 

若是模型綁定成功,則保存新增數據,而後經過RedirectToAction來重定向到表格頁面:

 

小結

這篇文章首先介紹了VS2015MVC項目的建立過程;而後簡要概述頁面執行的流程,從路由引擎到控制器,再由控制器到視圖,最後由視圖返回到瀏覽器,而模型是做爲控制器傳入視圖的參數,這樣清晰明瞭;最後使用VS提供的模板,建立了一個帶CRUD操做的數據訪問實例。

EF CodeFirst讓咱們的關注點從數據庫轉移到了模型,而模型又是MVC的核心所在,對模型進行恰當的數據註解,不只會影響數據庫的表結構,並且會影響瀏覽器端的數據驗證和服務端的數據驗證,所以下一篇文章咱們會詳細介紹一下數據註解。

下載示例源代碼

相關文章
相關標籤/搜索