|
上一節(jié):MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分頁(yè) 源碼下載:點(diǎn)我下載 目錄前言前面講解了如何創(chuàng)建一個(gè)查詢頁(yè)面并給查詢頁(yè)面添加排序、搜索及分頁(yè)功能。今天我們來(lái)講講如何向這個(gè)列表添加數(shù)據(jù)。 講解的順序?qū)凑仗砑訑?shù)據(jù)的步驟的時(shí)間順序來(lái)進(jìn)行,方便大家理清邏輯關(guān)系。本節(jié)將涉及前面講到的很多知識(shí)點(diǎn),而且還有很多新知識(shí)點(diǎn)。幫助大家溫故知新,融會(huì)貫通。 創(chuàng)建頁(yè)面預(yù)覽如下:
新建鏈接首先在之前創(chuàng)建好的查詢頁(yè)面上添加一個(gè)能夠跳轉(zhuǎn)到創(chuàng)建頁(yè)面的鏈接,將這個(gè)鏈接添加到標(biāo)題和搜索欄之間。代碼如下: <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> } 上面代碼中黃色部分就是添加的鏈接,這個(gè)ActionLink生成的HTML代碼如下: <a href="/Company/Create">Add New Worker</a> 可以看到這個(gè)鏈接訪問(wèn)的是CompanyController下的Create Action。下面來(lái)創(chuàng)建這個(gè)Action。 新建頁(yè)面Action打開文件~\Controllers\CompanyController.cs。在這個(gè)Controller中添加一個(gè)Create Action,如下所示: public ViewResult Create() { return View(); } 這么簡(jiǎn)單?對(duì)就是這樣,創(chuàng)建數(shù)據(jù)的頁(yè)面所有信息都需要用戶去填,自然不需要傳遞數(shù)據(jù),也就沒(méi)有什么操作。 這個(gè)Action調(diào)用了它對(duì)應(yīng)的View,那么我們就來(lái)創(chuàng)建這個(gè)View。 新建頁(yè)面View在~\Views\Company\文件夾下創(chuàng)建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 為了更好的進(jìn)行數(shù)據(jù)操作,Worker類做了改動(dòng),改動(dòng)之后的代碼如下: 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類庫(kù),這樣我們就可以在Worker類中添加元數(shù)據(jù)來(lái)在View中更好的操作數(shù)據(jù)。關(guān)于這部分內(nèi)容可以點(diǎn)這里進(jìn)一步了解。 看View的第13行代碼: @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" }) 這里的LabelFor函數(shù)用來(lái)顯示這個(gè)數(shù)據(jù)對(duì)應(yīng)的名稱,它會(huì)去找Worker類的FirstName對(duì)應(yīng)的數(shù)據(jù)名稱,也就是Model里的第15行: [Display(Name = "First Name")] 然后用Html把它顯示出來(lái),如下: <label class="control-label col-md-2" for="FirstName">First Name</label> View中的第15行: @Html.EditorFor(model => model.FirstName) 會(huì)根據(jù)Model中的第16行: [DataType(DataType.Text)] 來(lái)決定用哪種input元素來(lái)編輯數(shù)據(jù),既然是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 字段是必需的。"" 這一段是哪來(lái)的呢? 這是EditorFor函數(shù)讀取到Model中的第17行: [Required] 這一行表示這個(gè)數(shù)據(jù)是必填項(xiàng),如果不填則會(huì)顯示信息"First Name 字段是必需的。"。 在View中的第29行用到函數(shù)Html.EnumDropDownListFor,如下所示: @Html.EnumDropDownListFor(model => model.Sex) 這個(gè)函數(shù)可以把Enum類型的數(shù)據(jù)在頁(yè)面上以下拉菜單的形式顯示出來(lái)供人編輯。 不過(guò)這個(gè)函數(shù)可不是那么容易用,首先Visual Studio的版本必須是2013或者以上的,項(xiàng)目必須用的是MVC5,然后在菜單中選擇工具->庫(kù)程序包管理器-> 管理解決方案的NuGet程序包。如下所示選擇聯(lián)機(jī),在左上角搜索MVC然后安裝最新的MVC 5.2.2版。
更新好之后,這個(gè)函數(shù)就可以正常使用了。它會(huì)根據(jù)Sex這個(gè)Enum變量來(lái)生成下拉菜單。這個(gè)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函數(shù)用來(lái)驗(yàn)證數(shù)據(jù)的有效性。它根據(jù)在Model中這個(gè)屬性的類型來(lái)驗(yàn)證輸入的值是否符合要求。比如Rating這個(gè)屬性是Double類型的,那么在輸入數(shù)據(jù)時(shí),如果數(shù)據(jù)不是數(shù)字則會(huì)有相應(yīng)提示,并且不能提交。 View的第6、7、46行是如下所示的不帶參數(shù)的Form函數(shù)結(jié)構(gòu): @using (Html.BeginForm()){}這樣的結(jié)構(gòu)如果不帶任何參數(shù),則Form會(huì)以Post方法提交給本頁(yè)面對(duì)應(yīng)的Controller和Action,因此其生成的HTML代碼就是如下形式: <form action="/Company/Create" method="post"></form> 在View中使用了Bootstrap的橫向表單布局其結(jié)構(gòu)如下: <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> 顯示出來(lái)的效果如下所示:
每一行對(duì)應(yīng)一個(gè)屬性,左邊是屬性名,右邊是屬性對(duì)應(yīng)的編輯框。屬性名的col-md-2表示其占Form總寬度的2/12,col-md-10表示其占Form總寬度的10/12。這用到了Bootstrop的柵格系統(tǒng)。柵格系統(tǒng)詳細(xì)介紹請(qǐng)點(diǎn)這里。 View第8行@Html.AntiForgeryToken()函數(shù)的作用是抵御網(wǎng)頁(yè)跨站請(qǐng)求偽造漏洞(CSRF Cross-site request forgery)。這個(gè)漏洞可以盜用登錄用戶身份發(fā)送惡意請(qǐng)求。比如一個(gè)用戶登錄了網(wǎng)上銀行,然后訪問(wèn)攻擊者的網(wǎng)站,網(wǎng)站就會(huì)通過(guò)登錄用戶發(fā)出請(qǐng)求來(lái)獲取銀行信息。 View第11行使用Html.ValidationSummary(true)。表示只輸出Model級(jí)的驗(yàn)證錯(cuò)誤信息。其具體用法會(huì)在后面章節(jié)中詳細(xì)介紹。 上面這幾段對(duì)Create.cshtml文件中具有代表性的技術(shù)知識(shí)點(diǎn)做了詳細(xì)說(shuō)明,其他行不再贅述,有問(wèn)題請(qǐng)留言。 添加數(shù)據(jù)Action從上面代碼可以看出,Create.cshtml頁(yè)面會(huì)把數(shù)據(jù)提交給當(dāng)前頁(yè)面對(duì)應(yīng)的Controller和Action,因此我們就在CompanyController下寫處理提交的數(shù)據(jù)的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 } 注意,之前我們已經(jīng)寫了一個(gè)Create Action用來(lái)進(jìn)入添加頁(yè)面,這里的Create不是修改前面的Create。而是新建了一個(gè)Action。 第1行在這個(gè)Action前加[HttpPost]表示只有以Post方法請(qǐng)求Create Action的時(shí)候才會(huì)調(diào)用這個(gè)Action。 第2行ValidateAntiForgeryToken依然是為了防止跨站請(qǐng)求偽造攻擊而寫的代碼。 第3行Action的參數(shù)是以worker實(shí)例傳遞的。也就是說(shuō)Create.cshtml提交的4個(gè)值被賦值給work然后把worker傳遞給Create作為參數(shù)。而這個(gè)參數(shù)前面的[Bind(Include = "FirstName, LastName, Sex, Rating")]是為了防止過(guò)多提交(overposting)攻擊的。從Create.cshtml的代碼可以知道,這個(gè)頁(yè)面只會(huì)提交4個(gè)值。而黑客可以有辦法通過(guò)這個(gè)頁(yè)面提交更多的值給當(dāng)前Action,而這些多出來(lái)的值也會(huì)存在worker實(shí)例中被添加到數(shù)據(jù)庫(kù),這無(wú)疑是危險(xiǎn)的。因此[Bind(Include = "")]就限定了不管你提交多少值,我這個(gè)Action里只接受"FirstName, LastName, Sex, Rating"這4個(gè)值。保證了頁(yè)面的安全性。 第7行ModelState.IsValid表示提交的數(shù)據(jù)是否有效。比如對(duì)于一個(gè)類型為數(shù)字的屬性必須提交一個(gè)數(shù)字才算是有效。如果提交的數(shù)據(jù)有效則保存數(shù)據(jù)并且將頁(yè)面跳轉(zhuǎn)回Index.cshtml。 第16行ModelState.AddModelError()函數(shù)可以給Model添加一條錯(cuò)誤信息,函數(shù)的第一個(gè)參數(shù)是key,用于查找這個(gè)錯(cuò)誤信息,第二個(gè)參數(shù)是錯(cuò)誤信息的具體內(nèi)容。這個(gè)錯(cuò)誤信息可以在View中通過(guò)Html.ValidationMessage("unableToSave")來(lái)訪問(wèn)到。 查看結(jié)果點(diǎn)擊下圖的"Add New Worker"鏈接。
放空必填項(xiàng)或者輸入不合法數(shù)據(jù)出現(xiàn)提示信息如下:
填入正確信息如下:
點(diǎn)擊Submit按鈕,成功添加數(shù)據(jù)后的結(jié)果如下:
結(jié)尾終于又完成了一篇,再接再厲! 喜歡就推薦下吧! 本節(jié)主要參考:Implementing Basic CRUD Functionality with the Entity Framework in ASP.NET MVC Application 上一節(jié):MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分頁(yè) 作者:Slark.NET 出處:http://www.cnblogs.com/slark/ 本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。如有問(wèn)題或建議,請(qǐng)多多賜教,非常感謝。 |
|
|
來(lái)自: 昵稱10504424 > 《工作》