Pro ASP.Net MVC 3 Framework学习笔记之二
接着昨天的笔记:http://www.2cto.com/kf/201112/112885.html
为第一次的Demo添加动态输出(Dynamic Output)
整个应用程序平台的关键点就是构建动态的输出,在MVC中,构建数据是controller的工作,将数据作为HTML的呈现是View的工作,很明显这里有一个将数据从Controller传递到View的过程。其中的一种方式就是通过ViewBag,ViewBag是Controller基类的一个成员,它是一个动态的对象,我们可以给它赋予任意的属性值,并在View中呈现。修改Index Action如下:
public ViewResult Index()
{
int hour = DateTime.Now.Hour;
ViewBag.Greeting = hour < 12 ? "Good morning" : "Good afternoon";
return View();
}
我们给ViewBag赋予了一个Greeting的属性值,如果是系统时间是上午,Greeting的值就是"Good morning",下午则是"Good afternoon",前面说了ViewBag会将数据传递给View,修改Index View如下:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
@ViewBag.Greeting,zhangxuefei(from the view)
</div>
</body>
</html>
运行程序会出现我们预期的结果(上午显示:"Good morning,zhangxuefei(from the view)",下午则显示:"Good afternoon....")
上面我们体验了一把ViewBag。前面我们都只用到了V和C,并没有接触M,下面我们就来了解下M(Model)
假设情景:我的朋友决定举办一场除夕晚会,他希望我们给他做个网站,能够让他的朋友来登记下参与的情况和必要的信息。
主要有以下功能:
1.显示Party介绍的主页 2.登记的表单 3.表单进行必要的验证 4.登记完成后反馈邮件给他
接着修改刚才的View如下:
<div>
@ViewBag.Greeting,zhangxuefei(from the view)
<p>We're going to have an exciting party.<br /></p>
@Html.ActionLink("RSVP Now", "RSVPForm")
</div>
接下来要创建程序里面非常重要的一部分M(Model)
Model:是对现实世界的对象,过程和规则的展现,它定义了程序的主体,被誉为“领域”(Domain)。Model被称为领域模型,包含了C#对象,也叫领域对象,还包括了供我们操控的所有应用和方法。View和Controller以持久化的方式将领域(Domain)暴露给了客户端。
添加一个Model 类名为GuestResponse,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace PartyInvites.Models
{
public class GuestResponse
{
[Required(ErrorMessage = "Please enter your name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter your email")]
[RegularExpression(".+\\@.+\\..+", ErrorMessage = "Please enter a valid email address")]
public string Email { get; set; }
[Required(ErrorMessage = "Please enter your phone number")]
public string Phone { get; set; }
[Required(ErrorMessage = "Please specify whether you'll attend")]
public bool? WillAttend { get; set; }
}
}
这里我一并加上了对属性值的验证,后面会有介绍,验证也是asp.net mvc一个非常方便的地方。你可能留意到了,这里将WillAttend定义成了可空的类型,它的值包含true,false,and null,这里定义为可空非常必要,后面解释原因。
我们在主页View添加一个链接:@Html.ActionLink("RSVP Now", "RsvpForm")跳转到登记页面,MVC里面为我们提供了很多用于生成标准HTML元素的帮助类,HTML便是其中之一。这里的ActionLink()方法的第一个参数是连接显示的文本,第二个参数是处理该URL请求的Action是RsvpForm。你也不必急于去知道MVC为我们提供了哪些帮助类,我也不急,后面会有介绍,呵呵。
下面添加RsvpForm Action 如下所示:
[HttpGet]
public ViewResult RsvpForm()
{
return View();
}
然后添加一个强类型的View,这里的强类型概念和我们通常说的强类型Dataset是一个意思。这里我们要呈现的具体类型就是GuestResponse,就可以直接创建一个强类型的View,在右键添加View之前一定要编译程序。创建View如下图所示:
接下绑定表单:
@model PartyInvites.Models.GuestResponse @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>RsvpForm</title> //引入样式表,来控制验证信息的显示 <link rel="Stylesheet" href="@Href("~/Content/Site.css")" type="text/css" /> </head> <body> @using (Html.BeginForm()) { @Html.ValidationSummary() <p> Your name:@Html.TextBoxFor(x => x.Name)</p> <p> Your email:@Html.TextBoxFor(x => x.Email)</p> <p> Your phone:@Html.TextBoxFor(x => x.Phone)</p> <p> Will you attend? @Html.DropDownListFor(x => x.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="Submit RSVP" /> } </body> </html>
注意到红色部分,当我们创建强类型的View时,会多出这么一句。里面用到一个Lambda表达式,Lambda表达式都会用一个运算符"=>",读作:goes to.如果你跟我一样不熟悉
"=>"大可不必担忧会成为学习MVC的障碍,猛击这里了解"=>"。后面也有专门的介绍,慢慢来,不着急。当然你也完全可以不用x=>x.Name,也可以换成@Html.TextBox("Name"),@Html.TextBox("Email")等。只不过用"=>"更方便而且不容易写错属性名,因为x=>x.Name有智能提示。这里还涉及到一个Html.BeginForm()方法,它会帮助我们生成Form元素并配置Method,默认提交当前的URL,这里用using语句容易造成误解,这里的using和我们在ADO.NET里面写using是一样的,这里的using只是相当于我们不用去写</form>这样一个结束标签。
注意:对应asp.net WebForms,在一个WebForm仅仅支持一个带有runat="server"的form,并包含了ViewState和Postback逻辑,MVC里不会使用服务端的form,所有的forms都是通常情况下的HTML标签,呈现出来的HTML标签的ID也不会发生任何变化。
下面我要开始处理刚才创建的Form,刚才创建了一个RsvpForm的Action,在该Action的上面我加上一个Attribute[HttpGet],这个表示该Action只会处理Get请求,Form表单默认是Post请求,所以继续创建一个处理Post请求的Action,如下所示:
[HttpPost] public ViewResult RsvpForm(GuestResponse guestResponse) { //ToDo:Email guestResponse to the part organizer if (ModelState.IsValid)//如果验证通过才跳转到Thanks View { return View("Thanks", guestResponse); } else { //there is a validation error -redisplay the form return View(); } }
将处理Post和Get请求的C#方法重载成两个保持了代码的整洁,这里Action Method被同一个URL调用,MVC能够保证哪一个方法被调用,这里又一次体现了"约定胜于配置"的思想。上面的代码我导入了一个新的命名空间using PartyInvites.Models;
Model Binding(模型绑定):
上面有提到,不同的请求(Get/Post)会有对应了的Action来处理,这个是MVC的约定。当Action被调用来响应URL请求时,GuestResponse作为一个C#类又是怎样跟前面的
联系起来的呢?答案就是Model Binding
Model Binging:是MVC里面非常有用的功能,凭借引入了数据强转和key/value键值对被用来处理领域模型类型的属性,大致的过程是:
1.当创建表单数据发送到客户端时,创建了这些值对应的ID和Name属性(这些属性继承Model里面类的属性名)的HTML Input元素。
2.相应的,Model Binding的时候,Input元素的Names属性会被用来设置Model Class实例的属性值,然后传给Action处理。
我们可以看下页面的HTML代码:
(上面的描述可能不清楚,我只能说抱歉,现在我也只能理解到这里,后面有了更好的理解再分享)
Model Binding是非常强大而且可以自定义的功能,它替我们消除了处理HTTP请求的辛苦,让我们更加专注于处理C#对象而不用去处理Request.Form[]和Request.QueryString[]的值。回到上面的RsvpForm(),GuestResponse对象被作为参数传递给Action Method,Action Method(这里是RsvpForm())就可以自动处理来至表单的数据。后面的章节会深入Model Binding进行讲解,所以你如果对这里跟我一样不太明白,不要紧,不着急,后面就明白了,呵呵。
接下来创建Thanks视图(return View("Thanks", guestResponse)),如下所示:
@model PartyInvites.Models.GuestResponse
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Thanks</title>
</head>
<body>
@{
try
{
//这里主要用来发生邮件,方便吧,MVC提供了WebMail来帮助我们发送邮件
WebMail.SmtpServer = "smtp.qq.com";
WebMail.SmtpPort = 25;
WebMail.EnableSsl = false;
WebMail.UserName = "mszhangxuefei";
WebMail.Password = "不能说的秘密";
WebMail.From = "mszhangxuefei@foxmail.com";
WebMail.Send(Model.Email,"RSVP Notification", Model.Name + ((Model.WillAttend ?? false) ? "" : "不会") + "参加");
}
catch (Exception)
{
@:<b>Sorry-we couldn't send the email to confirm your RSVP.</b>
}
}
<div>
<h1>
Thank you,@Model.Name!</h1>
@if (Model.WillAttend == true)
{
@:It's greate 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.
}
</div>
</body>
</html>
Razor提供的@操作符,因为View是强类型的,所以我可以通过@Model.属性名,来得到值。
验证:在开始创建Model的时候,每个属性的上面添加了一些Attributes,这也是MVC非常方便的地方。在MVC里面,验证是领域模型里面的典型应用,而不是向WebForms里面在用户界面进行验证。这意味着我们可以只在一个地方定义验证的规则,它在其他任何引用了该model的地方生效,添加Attributes的时候需要添加一个命名空间:System.ComponentModel.DataAnnotations.
这里就可以解释下为什么我将WillAttend属性定义为可空的类型,主要方便这里的验证空值,当用户没有选择WillAttend时,验证就不会通过。当然为了将验证信息集中在一个地方显示,我用到了Html.ValidationSummary().
到这里,我们顺利的完成了朋友为了请人来参加除夕Party的交给我们的任务。到这里,前三章的笔记也就到这里解释了,后面会持续记录我学习的笔记。
我也是刚学习MVC3,笔记里面肯定会有错误,还请路过的大牛们多指导。如果能给向我一样的初学者一点点帮助,我就很开心了。
大家晚安
作者 Gabriel Zhang
相关新闻>>
- 发表评论
-
- 最新评论 更多>>