標籤:info tin persist ring textbox models fse ack function
前言
前面解說了怎樣建立一個查詢頁面並給查詢頁面加入排序、搜尋及分頁功能。今天我們來講講怎樣向這個列表加入資料。
解說的順序將依照加入資料的步驟的時間順序來進行,方便大家理清邏輯關係。
本節將涉及前面講到的非常多知識點,並且還有非常多新知識點。協助大家溫故知新,融會貫通。
建立頁面預覽例如以下:
建立連結
首先在之前建立好的查詢頁面上加入一個可以跳轉到建立頁面的連結。將這個連結加入到標題和搜尋欄之間。代碼例如以下:
<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視圖,寫入例如以下代碼:
@model SlarkInc.Models.Worker@{ ViewBag.Title = "Add New Worker";}<h2>Add New Worker</h2>@using (Html.BeginForm()){ @Html.AntiForgeryToken() <div class="form-horizontal"> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.LastName) @Html.ValidationMessageFor(model => model.LastName) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Sex, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EnumDropDownListFor(model => model.Sex) @Html.ValidationMessageFor(model => model.Sex) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Rating) @Html.ValidationMessageFor(model => model.Rating) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> @Html.Submit("Submit") </div> </div> </div>}<div> @Html.ActionLink("Back to List", "Index")</div>
View的第1行代碼例如以下所看到的,引入了Models目錄裡的Worker類。
@model SlarkInc.Models.Worker
為了更好的進行資料操作,Worker類做了修改,修改之後的代碼例如以下:
隱藏代碼using System.ComponentModel.DataAnnotations;namespace SlarkInc.Models{ public enum Sex { Male, Female } public class Worker { public int ID { get; set; } [Display(Name = "Last Name")] [DataType(DataType.Text)] [Required] public string LastName { get; set; } [Display(Name = "First Name")] [DataType(DataType.Text)] [Required] public string FirstName { get; set; } [Required] public Sex Sex { get; set; } public double? Rating { get; set; } }}
代碼中第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類型的資料在頁面上下面拉菜單的形式顯示出來供人編輯。
只是這個函數可不是那麼easy用,首先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。代碼例如以下:
[HttpPost][ValidateAntiForgeryToken]public ActionResult Create([Bind(Include = "FirstName, LastName, Sex, Rating")] Worker worker){ try { if (ModelState.IsValid) { db.Workers.Add(worker); db.SaveChanges(); return RedirectToAction("Index"); } } catch (DataException /* dex */) { ModelState.AddModelError("unableToSave","Unable to save changes.Try again, and if the problem persists see your system administrator."); } return View(worker);}
注意。之前我們已經寫了一個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"連結。
放空必填項或者輸入不合法資料出現提示資訊例如以下:
填入正確資訊例如以下:
點擊Submitbutton,成功加入資料後的結果例如以下:
結尾
最終又完畢了一篇,再接再厲!
ASP.Net MVC開發基礎學習筆記(8):建立資料頁面