第一話簡單介紹了一下Asp.Net MVC,接下來就慢慢進門看唄!
首先動態輸入還是接着昨天的項目修改着玩吧!
修改一天昨天的HomeController吧!(為了方便這次把注釋卸載代碼里,新同學們注意了)。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Hello_Asp.Net_Mvc.Controllers { public class HomeController : Controller { /// <summary> /// ActionResult:封裝一個操作方法的結果並用於代表該操作方法執行框架級操作。 /// ActionResult 類是操作結果的基類,第一話用的ViewResult返回類型都是從它派生的. /// </summary> public ActionResult Index() { var hour = DateTime.Now.Hour; //ViewBag獲取動態視圖數據字典 //ViewBage在程序運行(Runtime)時解析 this.ViewBag.Greeting = hour < 12 ? "早上好" : "下午好"; return this.View(); } } }
補充一點:ViewBag是動態對象,您可以指定任意屬性,呈現到頁面上。
這里就對代碼不做過多的解釋,要是那里還不懂可以聯系我,大家一起共同學習。
然后來看下前台Index.cshtml頁面吧!為了看我本地的時間,就隨便在代碼里加了一句,嘿嘿!
@{ ViewBag.Title = "Asp.Net Mvc Index"; } <h3>"當前時間":@DateTime.Now.Hour 點</h3> <h2>@this.ViewBag.Greeting!</h2>
到這里,跑起來看看結果如下圖2:
圖2.
接下來體驗MVC里的M->Model(模型)吧!
借鑒一下《Pro ASP.NET MVC 3 Framework》這本書里的例子吧!
首先,我們來假設一個場景,有一下幾點:
- 首先要有一個主頁來顯示聚會的信息
- 要有一個能回復的表單
- 表單要經行必要的驗證
- 登記完成后通過Email返回給派對的主人
Model(模型)用於封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法。“模型”有對數據直接訪問的權力,例如對數據庫的訪問。“模型”不依賴“視圖”和“控制器”,也就是說,模型不關心它會被如何顯示或是如何被操作。但是模型中數據的變化一般會通過一種刷新機制被公布。為了實現這種機制,那些用於監視此模型的視圖必須事先在此模型上注冊,從而,視圖可以了解在數據模型上發生的改變。說白了Model就是對現實世界的對象,過程和規則的展示,它定了主體被譽為“領域”(Domain)。Model被稱為領域模型,包含了C#對象,也叫領域對象,還包括了供我們操控的所有應用和方法。View和Controller以持久化的方式將領域(Domain)暴露給了客戶端。
接下來在我們項目的Models文件下添加一個model(模型)吧,叫GuestResponse,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Hello_Asp.Net_Mvc.Models { public class GuestResponse { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public bool? WillAttend { get; set; } //WillAttend可以是真,假,null } }
因為我們需要一個登記的表單,所以在首頁我們要給添加一個連接來引導用戶去我們的登錄表單,那我們來修改一下我們Index.cshtml頁面吧!
@{ ViewBag.Title = "Asp.Net Mvc Index"; } <h3>"當前時間":@DateTime.Now.Hour 點</h3> <h2>@this.ViewBag.Greeting!</h2> <div> <p>We're going to have an exciting party.<br /></p> @Html.ActionLink("RSVP Now", "RsvpFrom") </div>
OK!連接加好了,添加連接是為了引導用戶去登錄表單的視圖界面,那么我們的控制器(Controller)里面是不是應該對應要有一個返回視圖的Action(方法),那接下來就先寫這個Action(方法)吧!繼在我們的HomeController里面玩吧!代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Hello_Asp.Net_Mvc.Controllers { public class HomeController : Controller { /// <summary> /// ActionResult:封裝一個操作方法的結果並用於代表該操作方法執行框架級操作。 /// ActionResult 類是操作結果的基類,第一話用的ViewResult返回類型都是從它派生的. /// </summary> public ActionResult Index() { var hour = DateTime.Now.Hour; //ViewBag獲取動態視圖數據字典 //ViewBage在程序運行(Runtime)時解析 this.ViewBag.Greeting = hour < 12 ? "早上好" : "下午好"; return this.View(); } /// <summary> /// ViewResult:表示一個類,該類用於使用由 IViewEngine 對象返回的 IView 實例來呈現視圖。 /// ViewResult派生自ActionResult /// </summary> public ViewResult RsvpFrom() { return this.View(); } } }
返回視圖的Action(方法)好了,接下來就是視圖的創建了,我們需要創建一個強類型視圖(強類型的視圖是為了呈現特定的域類型),這里我們要呈現肯定就是我們寫的Model(模型)里的GuestResponse了,接下來添加視圖RsvpFrom吧!如圖3.
圖3.
強類型的視圖頁面建立好了然后就需要我們在這個頁面去完成那個登記表單了。RsvpFrom.cshtml的頁面代碼如下:
@model Hello_Asp.Net_Mvc.Models.GuestResponse @{ ViewBag.Title = "RsvpFrom"; } <h2>RsvpFrom</h2> @using (Html.BeginForm()) { <p>Your Name:@Html.TextBoxFor(h => h.Name)</p> <p>Your Email:@Html.TextBoxFor(h => h.Email)</p> <p>Your Phone:@Html.TextBoxFor(h => h.Phone)</p> <p> Will you atted? @Html.DropDownListFor(h=>h.WillAttend,new[] { new SelectListItem() { Text = "Yes,I'll be there", Value = bool.TrueString }, new SelectListItem() { Text = "No,I can't come", Value = bool.FalseString } },"Choose an option") </p> <input type="submit" value="RSVP SUBMIT" /> }
補充說明:可以明確看到代碼上面多了一句"@model Hello_Asp.Net_Mvc.Models.GuestResponse",這句就是對我們選擇強類型里GeuestResponse類的一個引用,當然我們選擇好,VS會自動把這東西引入進來。
現在我們首頁的連接就可以連接過來了,如下圖4.圖5.所示:
圖4.
圖5.
看似銜接完美無缺,但是新的問題出來了,就在我們的RsvpFrom.cshtml。這個視圖頁面呈現給我們是一個表單,但是正真處理這個表單的東西在HomeController(控制器)里的RsvpFrom Action(方法),RsvpFrom.cshtml只是用來呈現表單的罷了。試想一下,如果我們在填寫表單的時候不小心突然提交了一下,這個時候表達到底干了什么我不清楚,但是把我之前填寫的東西一下給搞沒了,究竟干了操作呢!這個時候,我們就需要表單處理了,提交表單不就是對服務器請求么,不就是"POST"和"GET"么!
先來了解一下這MVC里的Http Get 和 Http Post:
- Http Get:當瀏覽器有Get請求時,它的主要責任就是顯示最初的表單給用戶展示。
- Http Post:Post請求時,它主要負責提交和接受數據。
既然它們請求的URL一樣,但是個子的責任有不一樣,那么我們接下來就能很好的處理這個表單程序了,給HomeController(控制器)里添加一個相同的RsvpFrom的Action(方法),並讓他的屬性(特性)為HttpPost,具體改后的代碼,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Hello_Asp.Net_Mvc.Models; namespace Hello_Asp.Net_Mvc.Controllers { public class HomeController : Controller { /// <summary> /// ActionResult:封裝一個操作方法的結果並用於代表該操作方法執行框架級操作。 /// ActionResult 類是操作結果的基類,第一話用的ViewResult返回類型都是從它派生的. /// </summary> public ActionResult Index() { var hour = DateTime.Now.Hour; //ViewBag獲取動態視圖數據字典 //ViewBage在程序運行(Runtime)時解析 this.ViewBag.Greeting = hour < 12 ? "早上好" : "下午好"; return this.View(); } /// <summary> /// ViewResult:表示一個類,該類用於使用由 IViewEngine 對象返回的 IView 實例來呈現視圖。 /// ViewResult派生自ActionResult /// </summary> [HttpGet] public ViewResult RsvpFrom() { return this.View(); } [HttpPost] public ViewResult RsvpFrom(GuestResponse guestResponse) { return this.View("ThanksForyou",guestResponse); } } }
現在要是現在請求的話,你會發現找不到視圖,因為表單一定被我們處理了,你會發現當表單提交成功后,它會返回到一個叫"TanksForyou"的視圖頁面,更有意思的是他還是帶參數的,不錯這個類就是我們的Models文件夾里的GuestResponse類(model模型),那接續就來一場【使用模型綁定數據】的戲曲玩玩。那我們需要創建"TanksForyou"這個視圖頁面,沒有這個頁面我們的數據也沒地方去綁定啊!所謂"一個巴掌拍不響",那我就來建它吧!在HomeController里添加視圖TanksForyou,如下圖6所示。
圖6.創建完成后,我們在這個頁面的處理如下:
@model Hello_Asp.Net_Mvc.Models.GuestResponse @{ ViewBag.Title = "ThanksForyou"; } <h2>ThanksForyou</h2> <h1>Hi,Thanks you! @Model.Name</h1> @if (Model.WillAttend == true) { @:It's great that you're coming. The drinks are already in the fridge! } else { @:Sorry to hear that you can't make it, but thanks for letting us know. }
說明:創建的還是強類型視圖。
寫到這里我們來看看這個小程序現在能跑起來么!一路下來如下圖7-9.
圖7.
圖8
圖9.
o(∩_∩)o 已經是沒有問題的了!新同學們是不是想自己去試試么!怎么一看似乎一路風平浪靜,嘿嘿,肯定不會的了,就目前的小東西而言還存在很多問題,但看我在表單的輸入視乎還沒啥,但是用戶對表單進行非法操作,嘿嘿!新的問題(BUG)有暴露出來,所以表單驗證也是很重要的。
在MVC里驗證通常應用於Model(模型)或者理解"域模型",而不是在用戶接口。這意味着我們定義我們的驗證標准在一個地方,它在任何地方生效使用的模型類。
那我們就來驗證一下我們的Model(模型)吧!我們需要把GuestResponse模型修改為下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace Hello_Asp.Net_Mvc.Models { public class GuestResponse { [Required(ErrorMessage = "Please enter your name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter you email")] [RegularExpression(".+\\@.+\\..+", ErrorMessage = "Please enter a valid email")] public string Email { get; set; } [Required(ErrorMessage = "Please enter you phone number")] public string Phone { get; set; } [Required(ErrorMessage = "Please specift whether you'll attend")] public bool? WillAttend { get; set; } //WillAttend可以是真,假,null } }
代碼說明:上面紅色的引用的作用是:提供用於為 ASP.NET 動態數據控件定義元數據的特性類。也就是下面能看到那些中括號里面的東西。
模型驗證完了,現在就差一點就O了!還需要給表單添加一句驗證的代碼,RsvpFrom.cshtml修改的代碼如下:
@model Hello_Asp.Net_Mvc.Models.GuestResponse @{ ViewBag.Title = "RsvpFrom"; } <h2>RsvpFrom</h2> @using (Html.BeginForm()) { @Html.ValidationSummary() <p>Your Name:@Html.TextBoxFor(h => h.Name)</p> <p>Your Email:@Html.TextBoxFor(h => h.Email)</p> <p>Your Phone:@Html.TextBoxFor(h => h.Phone)</p> <p> Will you atted? @Html.DropDownListFor(h=>h.WillAttend,new[] { new SelectListItem() { Text = "Yes,I'll be there", Value = bool.TrueString }, new SelectListItem() { Text = "No,I can't come", Value = bool.FalseString } },"Choose an option") </p> <input type="submit" value="RSVP SUBMIT" /> }
說明:上面代碼紅色部分就是給表單添加驗證代碼。
還需要一點,那就是在特性為HttpPost的RsvpFrom(方法Action)也來判斷一下,判斷獲取的模型的數據是否有效,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Hello_Asp.Net_Mvc.Models; namespace Hello_Asp.Net_Mvc.Controllers { public class HomeController : Controller { /// <summary> /// ActionResult:封裝一個操作方法的結果並用於代表該操作方法執行框架級操作。 /// ActionResult 類是操作結果的基類,第一話用的ViewResult返回類型都是從它派生的. /// </summary> public ActionResult Index() { var hour = DateTime.Now.Hour; //ViewBag獲取動態視圖數據字典 //ViewBage在程序運行(Runtime)時解析 this.ViewBag.Greeting = hour < 12 ? "早上好" : "下午好"; return this.View(); } /// <summary> /// ViewResult:表示一個類,該類用於使用由 IViewEngine 對象返回的 IView 實例來呈現視圖。 /// ViewResult派生自ActionResult /// </summary> [HttpGet] public ViewResult RsvpFrom() { return this.View(); } [HttpPost] public ViewResult RsvpFrom(GuestResponse guestResponse) { //驗證獲取模型的數據是否有效 if (ModelState.IsValid) { return this.View("ThanksForyou", guestResponse); } else { return this.View(); } } } }
OK了!完工了!o(∩_∩)o .........
現在只需要看看驗證如何呢!看看下圖10.
圖10.今天就到此,呃!怎么感覺有點亂,願新同學們能看懂吧!
