1. 程式人生 > >【第二篇】ASP.NET MVC快速入門之資料註解(MVC5+EF6)

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

目錄

資料庫連線字串

上一篇文章中,我們使用MVC的模板自動生成了CRUD的全部操作,但是沒有配置資料庫連線字串,那麼資料存到什麼地方了?

開啟專案的App_Data目錄,你可以發現數據庫原來在這裡:

我們通過VS自帶的資料庫訪問工具,來看下錶結構和其中的資料,首先找到[伺服器資源管理器]面板,新增資料庫連線:

在新增連線嚮導對話方塊中,輸入伺服器名:(LocalDb)\MSSQLLocalDB,這個是VS2015自帶的LocalDb的伺服器例項名稱(如果你使用VS2013,這個名稱可能是:(LocalDB)\v11.0)。資料庫選擇我們剛剛建立的StudentDbContext

原來如果沒有顯式的指定資料庫連線字串,VS會使用預設的LocalDb例項,這個對應關係在Web.config中有定義:

<entityFramework>

       <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">

         <parameters>

              <parameter value="mssqllocaldb"
/>
</parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework
>

當然我們也可以明確指定資料庫連線字串:

<connectionStrings>

       <add name="DefaultConnection"

connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\AspNetMvc.QuickStart.Models.StudentDbContext.mdf;Initial Catalog=AspNetMvc.QuickStart.Models.StudentDbContext;Integrated Security=True"

         providerName="System.Data.SqlClient" />

</connectionStrings>

然後在程式碼中引用這個資料庫連線字串:

public class StudentDbContext : DbContext

{

       public StudentDbContext() : base("DefaultConnection")

       {

       }

 

       public DbSet<Student> Students { get; set; }

}

注意:如果使用的VS2013Data Source應該是(LocalDb)\v11.0,而VS2015對應的是(LocalDb)\MSSQLLocalDB

經過這個改變,在真正部署到MSSQL伺服器時,簡單修改資料庫連線字串就可以了。

資料庫表結構

開啟Students的表定義:

可以看下EF是怎麼將Student模型對映到資料庫表結構的:

1.模型中ID屬性的資料對映為表的主鍵。

2.模型中的string型別對映為表的nvarchar(MAX)

3.模型中的intDateTime分別對映為表的intdatetime型別。

再來看下上一篇文章中新增到表中的資料:

如果你之前有資料庫設計的經驗,會很容易發現這個表結構的問題:

1.NameMajor儲存字串,一般需要限制最大長度,比如nvarchar(200)

2.NameMajor列應該不允許為空。

那麼怎麼來實現這兩個需求呢?直接修改資料庫肯定是不行的!

資料註解

我們應該從模型入手,還記得我們在上一篇文章結尾說的那句話嗎,資料模型不僅會影響資料庫的表結構,還會控制MVC檢視層的客戶端驗證和控制器層的伺服器端驗證。

修改Student模型類,新增適當的資料註解:

public class Student

{

       public int ID { get; set; }

 

       [Required]

       [StringLength(200)]

       public string Name { get; set; }

 

       public int Gender { get; set; }

 

       [Required]

       [StringLength(200)]

       public string Major { get; set; }

 

       public DateTime EntranceDate { get; set; }

}

如果輸入[Required]時沒有智慧感知,很可能是沒有引用相應的名稱空間,VS可以很方便的協助我們新增:

這樣就會在檔案頭部新增如下引用:

using System.ComponentModel.DataAnnotations;

直接執行專案(Ctrl+F5),此時我們會看到如下的錯誤頁面:

相信使用EF的同學都會遇到這個頁面,上面的提示也很明確,包含兩個層次的資訊:

1.資料庫建立之後模型改變了。

2.可以使用資料遷移來更新資料庫。

資料遷移(Migrations

VS[工具]選單中,找到Nuget包管理器控制檯:

啟用資料遷移

在控制檯中輸入如下命令:Enable-Migrations

這時會在專案目錄中增加一個Migrations資料夾,裡面放置了兩個檔案:

EF會通過C#程式碼的方式將每一次對模型的修改儲存到這個資料夾中,現在來看下生成的檔案內容:

每個遷移檔案,都包含UpDown兩個重寫函式,分別對應於更新和回退。上面的程式碼也很直白,Up函式中建立一個Students表,定義表結構並指定ID主鍵(PrimaryKey),Down函式用來回退操作,裡面簡單的刪除了Students表。

可以看到,這裡的建立表操作並沒有使用最新的模型(Name列沒有nullable的設定),因為這是初始模型對應的表結構,EF會在資料庫中自動生成一個名為__MigrationHistory表來跟蹤資料庫的狀態。

增加遷移項

增加遷移項需要我們手工來進行,在程式包管理器控制檯中,輸入如下命令:

Add-Migration Add_Annotation_Name_Major

這時會在Migrations目錄下生成遷移檔案,檔案是以[時間+遷移名]命名的,方便查詢:

201612160406415_Add_Annotation_Name_Major.cs

更新到資料庫

此時,資料庫尚未改變,我們還需要手工命令來更新資料庫:

Update-Database

此時,再來檢視資料庫中Students的表結構:

Name列的資料型別和是否允許Null都已經改變了。

在真實的專案中,資料庫可能部署在遠端伺服器中,這時我們就不能直接在VS中通過Update-Database來更新資料庫了。

不過我們可以生成更新SQL指令碼,然後拿到資料庫伺服器上執行。生成這個SQL指令碼的方法:

Update-Database   -Script

-SourceMigration: InitialCreate

-TargetMigration: Add_Annotation_Name_Major

來看下生成的SQL更新指令碼:

有了這個SQL更新指令碼,我們就可以方便的更新遠端資料庫了。

檢視的客戶端驗證

現在執行專案,轉到建立頁面:

可以看到,如果Name為空則會有錯誤提示資訊,而Major輸入字串過多,也會有提示資訊,而這些設定是來自模型的資料註解。

這個客戶端驗證是有jQueryvalidation外掛提供的:

如果你檢視頁面原始碼,會發現Major輸入框的input標籤上有相應的自定義屬性data-val-length-max=200data-val-length,而這些屬性值正是來自於模型的資料註解。

控制器的伺服器端驗證

在啟用JavaScript的情況下,由於所有的錯誤輸入在客戶端就會被攔截,所以根本到達不了伺服器,不過這並不表示惡意使用者無法提交錯誤的輸入,有很多種方法可以做到:

禁用JavaScript

不同瀏覽器禁用JavaScript的方法不同,在Chrome中,F12開啟開發工具,然後找到設定對話方塊:

此時提交頁面,你會看到和前面完全相同的頁面,由於本地執行速度很快,你甚至可能沒意識已經發起了一次HTTP POST請求,而顯示錯誤提示的頁面來自伺服器,而不是客戶端:

響應正文包含如下內容,其中錯誤資訊是伺服器端生成的:

<div class="form-group">

       <label class="control-label col-md-2" for="Name">Name</label>

       <div class="col-md-10">

              <input class="input-validation-error form-control text-box single-line" data-val="true" data-val-length="欄位 Name 必須是最大長度為 200 的字串。" data-val-length-max="200" data-val-required="Name 欄位是必需的。" id="Name" name="Name" type="text" value="" />

              <span class="field-validation-error text-danger" data-valmsg-for="Name" data-valmsg-replace="true">Name 欄位是必需的。</span>

       </div>

</div>

此時再回過頭來看下Students控制器中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);

}

如果驗證失敗,則不更新資料庫,並返回帶Student模型的檢視。

模擬POST請求

有很多工具可以模擬POST,這裡我們講解如果使用Fiddler來模擬項伺服器提交POST請求。

開啟Fiddler,就開始自動監測所有的HTTP請求,這時我們重新整理Create頁面,並在JavaScript禁用的情況下,提交表單,這時會有兩個請求:

首先選中左側的第二個請求,右側面板中選擇Inspectors->WebForms,下面會顯示三個窗格:

1.QueryString:當前請求的URL查詢字串。

2.BodyPOST請求的表單引數。

3.第三部分:響應正文,我們可以看到伺服器端返回的錯誤資訊。

現在切換到Composer選項卡,我們可以在這裡面模擬POST請求:

上面有一段提示資訊:使用這個頁面建立一個請求。你可以通過拖拽的方式從左側會話列表中拷貝一個之前的請求。

這就方便多了,我們從左側選中第二個請求並拖拽到本頁面:

這時頁面背景變成明顯的綠色以作提示,拖拽結束:

這時,Fiddler自動幫我們設定了模擬POST請求的引數,拷貝自之前的某個請求,這時的[Request Body]是經過URL編碼的,我們可以方便的進行解碼:

我們把這段程式碼修改成:

__RequestVerificationToken=wwoxICDootbixw8YMiFIOU1WW95QSCicREsWLeewlSAE28sdyEA0ZChlY0nfuOlxu2WDIjcrx086GYkaBOAtewyARWbeRZp0kD6tRt-hyAs1&Name=張三石&Gender=1&Major=&EntranceDate=2000-09-01

把這段字串拷貝到Fiddler中的[Request Body],並點選[Execute]按鈕,這時會發起一個新的模擬請求:

注意這個請求並不是從頁面發出的,而是通過工具模擬的HTTP POST請求,並且我們還修改了其中的表單引數(Name=張三石,Major=空字串),這樣當然也就會躲開瀏覽器端的JavaScript驗證規則,但是還是無法穿透伺服器端的驗證。

這也正是MVC中資料註解帶來的便利,一個地方定義,三個地方使用(資料庫表結構、客戶端驗證,伺服器端驗證)。

小結

本章我們首先查看了EF自動生成的資料庫結構,然後為資料模型新增資料註解,繼而介紹了資料遷移的工作過程。資料註解不僅對資料庫表結構產生影響,而且會應用到前臺的客戶端驗證和伺服器端驗證,接下來我們詳細講解了兩則躲避客戶端驗證的手段,分別為禁用JavaScript和模擬POST請求。從而更加深刻的認識到資料註解給我們提供的便利:一個地方定義,三個地方使用(資料庫表結構、客戶端驗證,伺服器端驗證)

在建立新使用者頁面,我們可以看到兩個安全相關的程式碼(ValidateAntiForgeryTokenBind),它們分別用於阻止CSRF跨站請求偽造和Over-Posting過多提交攻擊,下一篇文章我們會詳細介紹。

相關推薦

第二ASP.NET MVC快速入門資料註解MVC5+EF6

目錄 資料庫連線字串 上一篇文章中,我們使用MVC的模板自動生成了CRUD的全部操作,但是沒有配置資料庫連線字串,那麼資料存到什麼地方了? 開啟專案的App_Data目錄,你可以發現數據庫原來在這裡: 我們通過VS自帶的資料庫訪問工具,來看下錶結構和

第一ASP.NET MVC快速入門資料庫操作MVC5+EF6

目錄 新建專案 開啟VS2015,找到選單項[檔案->新建->專案],打開向導對話方塊: 注意我們的選擇項: 1.執行平臺:.NET FrameWork 4.5 2.專案模板:ASP.NET Web Application (.NET Framew

第三ASP.NET MVC快速入門安全策略MVC5+EF6

對象 code word 單身 script ticket bsp 金額 class 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門之

第四ASP.NET MVC快速入門完整示例MVC5+EF6

redirect name php sql語句 rop 方法 輸入框 一次 編輯 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門

第二ASP.NET MVC快速入門數據註解MVC5+EF6

red 數據庫結構 varchar model 菜單 錯誤提示 edi 還需 問題 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入

第一ASP.NET MVC快速入門數據庫操作MVC5+EF6

c項目 教程 建數據庫 因此 F5 ctr 文件頭部 lec 跨站請求偽造 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門之安全

番外ASP.NET MVC快速入門免費jQuery控件庫MVC5+EF6

south ade 批量刪除 HP 存儲 重新 mode eve 穩定 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門之安全策略

番外ASP.NET MVC快速入門免費jQuery控制元件庫MVC5+EF6

目錄 FineUIMvc簡介 FineUIMvc 是基於 jQuery 的專業 ASP.NET MVC 控制元件庫,其前身是基於 WebForms 的開源控制元件庫 FineUI(歷時9年120多個版本)。FineUIMvc(基礎版)包含開源版的全部功能,支援 30 種內建主題和 

隨筆系列Asp.Net Mvc分頁控件PagedList的使用方法及配置

provide 自動添加 pac png eight 鼠標 技術分享 apps con     企業在做Asp.Net Mvc開發過程中,很多時候都是一些CRUD,最基本的就是一個列表頁面,然後附帶一些功能按鈕。如果有數據列表,大多數就會涉及到對數據進行分頁,這次就介紹一下

第二SAP ABAP7.50新語法OPEN SQL

原文連結:SAP ABAP7.50系列之OPEN SQL 公眾號:SAP Technical 前言部分 當使用CDS實體的名稱作為資料來源訪問SELECT中的CDS檢視時,此檢視在其SELECT列表中釋出關聯_assoc以供外部使用,則這些關聯可用作路徑表示式的根元素。同樣的宣告。在路徑表示式中,關聯名

asp.net mvc 模組化開發第一章平臺介紹

基本框架是平臺+模組,其實說實在我也不知道這算框架還是算設計,或者說什麼都不算,希望大神們不要見笑,暫且我們叫他框架吧?這種框架源自於我上一家公司,當時我們公司有一個建站平臺和大家現在用CMS系統很像,不過功能沒有那麼強大,但是非常實用。這個平臺我用了將近三年,給我最大的感受

ASP.NET MVC 如何使用自定義過濾器篩選器

owa 分享圖片 *** htm 匿名訪問 net 控制 -- 三種 原文:ASP.NET MVC 如何使用自定義過濾器(篩選器)繼承*****Attribute(篩選器三種具體類)-->重寫方法-->標記在控制器 或者 方法上面 [類名(類屬性 =

hbase快速入門---表設計使用建議

ØColumn Family 建議不要在一張表裡定義多個的column family。目前Hbase並不能很好的處理超過2~3個column family的表。因為某個column family在f

ASP.NET Core快速入門 RoutingMiddleware介紹以及MVC引入

pre configure onf mvc tin 常用 esp red 引入 前言 前面我們介紹了使用app.Map來配置路由,但是對於一般不是特別大的項目來說,我們不使用Map來進行路由配置。 配置路由 我們首先需要在Startup.cs文件中的Configu

ASP.NET Core快速入門十四MVC開發:UI、 EF + Identity實現

dfa models cti ted lec inpu word pri numeric 前言 之前我們進行了MVC的web頁面的Cookie-based認證實現,接下來的開發我們要基於之前的MvcCookieAuthSample項目做修改。 MvcCookieAuth

記錄ASP.NET MVC View 移動版瀏覽的奇怪問題

手機瀏覽器 超鏈接 jquery 記錄 元素 ASP.NET MVC View 中的一段代碼:<span id="span_Id">@Model.ID</span>沒什麽問題吧,瀏覽器瀏覽正常,查看元素為:<span id="span_Id">12345

ASP.NET Core快速入門準備CentOS和Nginx環境

正常 b- 進入 運行 ins 輸入 最小 我們 -128 基本軟件 VMware虛擬機 centos:http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso

ASP.NET Core快速入門在CentOS上安裝.NET Core運行時、部署到CentOS

ati libunwind serve code api cal 之前 prompt conn 下載.NET Core SDK 下載地址:https://www.microsoft.com/net/download/windows 第一步:Add the dotne

ASP.NET Core快速入門部署到IIS

圖片 cor .com servers 訪問 publish img 控制臺 -m 原文:【ASP.NET Core快速入門】(二)部署到IIS配置IIS模塊 ASP.NET Core Module載地址:https://docs.microsoft.com/en-us/

視頻ASP.NET Core MVC 2.* 入門

配置 page bili http www 三方庫 play help uget 比較初級的入門教程,網址在B站:https://www.bilibili.com/video/av33728783/ 內容如下: 1. ASP.NET Core 簡介和開發工具 2. A