第二话 Asp.Net MVC 3.0【动态输出和Model(模型)应用】
第一话简单介绍了一下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.今天就到此,呃!怎么感觉有点乱,愿新同学们能看懂吧!