Slark.NET-博客園 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-create.html
上一節:MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分頁
下一節:MVC5 + EF6 + Bootstrap3 (13) 查看詳情、編輯數據、刪除數據
源碼下載:點我下載
目錄
前言
前面講解了如何創建一個查詢頁面並給查詢頁面添加排序、搜索及分頁功能。今天我們來講講如何向這個列表添加數據。
講解的順序將按照添加數據的步驟的時間順序來進行,方便大家理清邏輯關系。本節將涉及前面講到的很多知識點,而且還有很多新知識點。幫助大家溫故知新,融會貫通。
創建頁面預覽如下:

新建鏈接
首先在之前創建好的查詢頁面上添加一個能夠跳轉到創建頁面的鏈接,將這個鏈接添加到標題和搜索欄之間。代碼如下:
<h2>Students</h2> <p> @Html.ActionLink("Create New", "Create") </p> @using (Html.BeginForm("Index","Student", FormMethod.Get)) { <p> Find by name:@Html.TextBox("SearchString",ViewBag.CurrentFilter as string) <input type="submit" value="Search"/> </p> }
上面代碼中黃色部分就是添加的鏈接,這個ActionLink生成的HTML代碼如下:
<a href="/Company/Create">Add New Worker</a>
可以看到這個鏈接訪問的是CompanyController下的Create Action。下面來創建這個Action。
新建頁面Action
打開文件~\Controllers\CompanyController.cs。在這個Controller中添加一個Create Action,如下所示:
public ViewResult Create() { return View(); }
這么簡單?對就是這樣,創建數據的頁面所有信息都需要用戶去填,自然不需要傳遞數據,也就沒有什么操作。
這個Action調用了它對應的View,那么我們就來創建這個View。
新建頁面View
在~\Views\Company\文件夾下創建Create.cshtml視圖,寫入如下代碼:
1 @model SlarkInc.Models.Worker 2 @{ 3 ViewBag.Title = "Add New Worker"; 4 } 5 <h2>Add New Worker</h2> 6 @using (Html.BeginForm()) 7 { 8 @Html.AntiForgeryToken() 9 <div class="form-horizontal"> 10 <hr /> 11 @Html.ValidationSummary(true) 12 <div class="form-group"> 13 @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" }) 14 <div class="col-md-10"> 15 @Html.EditorFor(model => model.FirstName) 16 @Html.ValidationMessageFor(model => model.FirstName) 17 </div> 18 </div> 19 <div class="form-group"> 20 @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" }) 21 <div class="col-md-10"> 22 @Html.EditorFor(model => model.LastName) 23 @Html.ValidationMessageFor(model => model.LastName) 24 </div> 25 </div> 26 <div class="form-group"> 27 @Html.LabelFor(model => model.Sex, new { @class = "control-label col-md-2" }) 28 <div class="col-md-10"> 29 @Html.EnumDropDownListFor(model => model.Sex) 30 @Html.ValidationMessageFor(model => model.Sex) 31 </div> 32 </div> 33 <div class="form-group"> 34 @Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" }) 35 <div class="col-md-10"> 36 @Html.EditorFor(model => model.Rating) 37 @Html.ValidationMessageFor(model => model.Rating) 38 </div> 39 </div> 40 <div class="form-group"> 41 <div class="col-md-offset-2 col-md-10"> 42 @Html.Submit("Submit") 43 </div> 44 </div> 45 </div> 46 } 47 <div> 48 @Html.ActionLink("Back to List", "Index") 49 </div>
View的第1行代碼如下所示,引入了Models文件夾里的Worker類。
@model SlarkInc.Models.Worker
為了更好的進行數據操作,Worker類做了改動,改動之后的代碼如下:
1 using System.ComponentModel.DataAnnotations; 2 namespace SlarkInc.Models 3 { 4 public enum Sex 5 { 6 Male, Female 7 } 8 public class Worker 9 { 10 public int ID { get; set; } 11 [Display(Name = "Last Name")] 12 [DataType(DataType.Text)] 13 [Required] 14 public string LastName { get; set; } 15 [Display(Name = "First Name")] 16 [DataType(DataType.Text)] 17 [Required] 18 public string FirstName { get; set; } 19 [Required] 20 public Sex Sex { get; set; } 21 public double? Rating { get; set; } 22 } 23 }
代碼中第1行引入了DataAnnotations類庫,這樣我們就可以在Worker類中添加元數據來在View中更好的操作數據。關於這部分內容可以點這里進一步了解。
看View的第13行代碼:
@Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
這里的LabelFor函數用來顯示這個數據對應的名稱,它會去找Worker類的FirstName對應的數據名稱,也就是Model里的第15行:
[Display(Name = "First Name")]
然后用Html把它顯示出來,如下:
<label class="control-label col-md-2" for="FirstName">First Name</label>
View中的第15行:
@Html.EditorFor(model => model.FirstName)
會根據Model中的第16行:
[DataType(DataType.Text)]
來決定用哪種input元素來編輯數據,既然是Text類型的,那就用type="text"的input,如下所示:
<input class="text-box single-line" data-val="true" data-val-required="First Name 字段是必需的。" id="FirstName" name="FirstName" type="text" value="" />
那上面的代碼中 "data-val-required="First Name 字段是必需的。"" 這一段是哪來的呢?
這是EditorFor函數讀取到Model中的第17行:
[Required]
這一行表示這個數據是必填項,如果不填則會顯示信息"First Name 字段是必需的。"。
在View中的第29行用到函數Html.EnumDropDownListFor,如下所示:
@Html.EnumDropDownListFor(model => model.Sex)
這個函數可以把Enum類型的數據在頁面上以下拉菜單的形式顯示出來供人編輯。
不過這個函數可不是那么容易用,首先Visual Studio的版本必須是2013或者以上的,項目必須用的是MVC5,然后在菜單中選擇工具->庫程序包管理器-> 管理解決方案的NuGet程序包。如下所示選擇聯機,在左上角搜索MVC然后安裝最新的MVC 5.2.2版。

更新好之后,這個函數就可以正常使用了。它會根據Sex這個Enum變量來生成下拉菜單。這個Enum的定義如下:
public enum Sex { Male, Female }
那么它生成的下拉菜單代碼如下:
<select data-val="true" data-val-required="Sex 字段是必需的。" id="Sex" name="Sex"> <option selected="selected" value="0">Male</option> <option value="1">Female</option> </select>
View的第16行代碼:
@Html.ValidationMessageFor(model => model.FirstName)
其中ValidationMessageFor函數用來驗證數據的有效性。它根據在Model中這個屬性的類型來驗證輸入的值是否符合要求。比如Rating這個屬性是Double類型的,那么在輸入數據時,如果數據不是數字則會有相應提示,並且不能提交。
View的第6、7、46行是如下所示的不帶參數的Form函數結構:
@using (Html.BeginForm()){}
這樣的結構如果不帶任何參數,則Form會以Post方法提交給本頁面對應的Controller和Action,因此其生成的HTML代碼就是如下形式:
<form action="/Company/Create" method="post"></form>
在View中使用了Bootstrap的橫向表單布局其結構如下:
<div class="form-horizontal"> <div class="form-group"> <label class="control-label col-md-2" for=""></label> <div class="col-md-10"> </div> </div> <div class="form-group"> <label class="control-label col-md-2" for=""></label> <div class="col-md-10"> </div> </div> </div>
顯示出來的效果如下所示:

每一行對應一個屬性,左邊是屬性名,右邊是屬性對應的編輯框。屬性名的col-md-2表示其占Form總寬度的2/12,col-md-10表示其占Form總寬度的10/12。這用到了Bootstrop的柵格系統。柵格系統詳細介紹請點這里。
View第8行@Html.AntiForgeryToken()函數的作用是抵御網頁跨站請求偽造漏洞(CSRF Cross-site request forgery)。這個漏洞可以盜用登錄用戶身份發送惡意請求。比如一個用戶登錄了網上銀行,然后訪問攻擊者的網站,網站就會通過登錄用戶發出請求來獲取銀行信息。
View第11行使用Html.ValidationSummary(true)。表示只輸出Model級的驗證錯誤信息。其具體用法會在后面章節中詳細介紹。
上面這幾段對Create.cshtml文件中具有代表性的技術知識點做了詳細說明,其他行不再贅述,有問題請留言。
添加數據Action
從上面代碼可以看出,Create.cshtml頁面會把數據提交給當前頁面對應的Controller和Action,因此我們就在CompanyController下寫處理提交的數據的Action。代碼如下:
1 [HttpPost] 2 [ValidateAntiForgeryToken] 3 public ActionResult Create([Bind(Include = "FirstName, LastName, Sex, Rating")] Worker worker) 4 { 5 try 6 { 7 if (ModelState.IsValid) 8 { 9 db.Workers.Add(worker); 10 db.SaveChanges(); 11 return RedirectToAction("Index"); 12 } 13 } 14 catch (DataException /* dex */) 15 { 16 ModelState.AddModelError("unableToSave","Unable to save changes.Try again, and if the problem persists see your system administrator."); 17 } 18 return View(worker); 19 }
注意,之前我們已經寫了一個Create Action用來進入添加頁面,這里的Create不是修改前面的Create。而是新建了一個Action。
第1行在這個Action前加[HttpPost]表示只有以Post方法請求Create Action的時候才會調用這個Action。
第2行ValidateAntiForgeryToken依然是為了防止跨站請求偽造攻擊而寫的代碼。
第3行Action的參數是以worker實例傳遞的。也就是說Create.cshtml提交的4個值被賦值給work然后把worker傳遞給Create作為參數。而這個參數前面的[Bind(Include = "FirstName, LastName, Sex, Rating")]是為了防止過多提交(overposting)攻擊的。從Create.cshtml的代碼可以知道,這個頁面只會提交4個值。而黑客可以有辦法通過這個頁面提交更多的值給當前Action,而這些多出來的值也會存在worker實例中被添加到數據庫,這無疑是危險的。因此[Bind(Include = "")]就限定了不管你提交多少值,我這個Action里只接受"FirstName, LastName, Sex, Rating"這4個值。保證了頁面的安全性。
第7行ModelState.IsValid表示提交的數據是否有效。比如對於一個類型為數字的屬性必須提交一個數字才算是有效。如果提交的數據有效則保存數據並且將頁面跳轉回Index.cshtml。
第16行ModelState.AddModelError()函數可以給Model添加一條錯誤信息,函數的第一個參數是key,用於查找這個錯誤信息,第二個參數是錯誤信息的具體內容。這個錯誤信息可以在View中通過Html.ValidationMessage("unableToSave")來訪問到。
查看結果
點擊下圖的"Add New Worker"鏈接。

放空必填項或者輸入不合法數據出現提示信息如下:

填入正確信息如下:

點擊Submit按鈕,成功添加數據后的結果如下:

結尾
終於又完成了一篇,再接再厲!
喜歡就推薦下吧!
本節主要參考:Implementing Basic CRUD Functionality with the Entity Framework in ASP.NET MVC Application
上一節:MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分頁
下一節:MVC5 + EF6 + Bootstrap3 (13) 查看詳情、編輯數據、刪除數據
作者:Slark.NET
出處:http://www.cnblogs.com/slark/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如有問題或建議,請多多賜教,非常感謝。
