Zachary.XiaoZhen - 梦想的天空

跟小静学MVC3[02]--从注册模块实战MVC新特性

上一节我们创建了自己的第一个MVC3项目,并了解了Controller和View的添加方法。今天我们将仿照大米返利网注册模块写个小例子,来进一步了解Model、Action、Form等相关内容。

情景假设

  • 首页--欢迎页面,简单介绍大米返利网,并提供注册链接;
  • 注册--用户使用网站之前要先注册为会员,注册页面还要对用户填写的信息进行有效性验证;

          image

  • 注册完成--完成之后会跳转到一个提示页面,并向用户邮箱发送一封邮件。

一. 首页

1. 将上一节的Index页面用作首页,再添加一些说明文字。

首页 View代码
@{
    ViewBag.Title = "首页";
}
<h2>@ViewBag.hello</h2>
<p>大米返利网提供淘宝网等多家商城的返现优惠,<br/>
    返现比例高,提现速度快,注册赠1元,满3元提现。</p>
<p>点此注册</p>

 

image

接下来我们就要为“点此注册”提供链接页面了。

二. 添加注册页面

1. 创建数据Model

MVC中的M代表的领域模型,是应用程序中极其重要的部分之一,一个设计完好的MVC项目往往从设计完好的model开始,然后在此基础上继续添加controller和view。在我们的项目中,model是对现实世界对象的封装,定义规则、处理等等。具体实现时Model一般就是对项目中通用性对象的属性、方法进行封装而来的C#类,然后controller和view以一定的方式暴露给客户端。

接下来我们添加一个用户信息的model类:右键models文件夹->Add->Class->UserInfo.cs->Ok.

UserInfo.cs Code
/// <summary>
    
/// 注册用户实体
    
/// </summary>
    public class UserInfo
    {
        /// <summary>
        
/// 自动编号
        
/// </summary>
        public int Id { getset; }

        /// <summary>
        
/// 用户名
        
/// </summary>
        public string UserName { getset; }

        /// <summary>
        
/// 密码(明文简单示例)
        
/// </summary>
        public string Password { getset; }

        /// <summary>
        
/// qq号码
        
/// </summary>
        public string QQ { getset; }

        /// <summary>
        
/// 邮箱地址
        
/// </summary>
        public string Email { getset; }
    }

2. 添加Action

在IndexController中添加新的action:

        //注册
        public ActionResult Register()
        {
            return View();
        }

3. 添加强类型View

  • 创建view:强类型view目的是展现针对具体类型的实体,指定具体类型之后MVC会为其提供许多快捷的操作。需要注意的是,在添加强类型View之前,我们要先编译整个MVC项目,否则添加View时就会找不到先前添加的UserInfo实体。

添加步骤:

在Register Action代码块内右键->Add View->选中 Create a strongly type view复选框->Model class下拉框选择UserInfo->提供的模板选择Empty->Add。如下图所示:

image

添加完成之后我们发现新添加的View是以@model的Razor代码开头的。接下来我们将会看到,这正式强类型view以及它能提供诸多便捷的关键所在。

三、编辑表单

1. View代码

<h1>大米返利网</h1>
@using(Html.BeginForm())
{
    <p>用户名:@Html.TextBoxFor(m=>m.UserName)</p>
    <p>密码:@Html.PasswordFor(m=>m.Password)</p>
    <p>确认密码:@Html.PasswordFor(m=>m.Password)</p>
    <p>QQ:@Html.TextBoxFor(m=>m.QQ)</p>
    <p>Email:@Html.TextBoxFor(m=>m.Email)</p>
    <input type="submit" value="马上注册"/>
}

 

这里用的是Razor语法,使用过程中VS为我们提供了丰富的智能感知。以前不熟悉的同学可能会看着满眼的@符号不太自在,用一段时间就该上瘾了,因为它真的很好上手。运行效果如下:

image

2. Html几个helper方法:

首先,我们看一下页面源代码:


页面源代码
<h1>大米返利网</h1>

<form action="/index/register" method="post">

<p>用户名:<input id="UserName" name="UserName" type="text" value="" /></p>

<p>密码:<input id="Password" name="Password" type="password" /></p>

<p>确认密码:<input id="Password" name="Password" type="password" /></p>

<p>QQ:<input id="QQ" name="QQ" type="text" value="" /></p>

<p>Email:<input id="Email" name="Email" type="text" value="" /></p>

<input type="submit" value="马上注册"/>

</form> 
  • 不难看出,通过Razor语法中的Html helper方法,将Model中的属性用Input控件形式展现出来了。例如
@Html.TextBoxFor(m=>m.UserName)

生成html时,input控件type=”text”, id和name属性都被赋值为"UserName“。对应html代码为:

<input id="UserName" name="UserName" type="text" value="" />
  • 对于强类型view,书写lamda语法时有着丰富的智能感知。如果不想写成lamda形式,还可以这样 @Html.TextBoxFor(“UserName”)
  • Html.BeginForm:

代码格式为@using(Html.BeginForm()){   …},通常使用using关键字是为了走出花括号时释放较占资源的对象,而在这里可以理解为关闭<form>标签。生成form属性时,默认的action会提交回当前的url,而method默认设置为post。最终生成的html源码为:<form action="/index/register" method="post"> ……</form>。

另外,在WebForm开发时,每个页面只允许使用一个服务端form,并且包含ViewState以及postback逻辑,而在MVC中是没有服务器端form这个概念的,没有ViewState以及postback机制,每个页面可以放置多个form。

  • Html.ActionLink:用来添加action页面的链接,我们可以在首页为“点此注册”添加链接:
@Html.ActionLink("点此注册","Register","Index")

四. 表单提交

  1.  HttpGet和HttpPost:

为了接收并处理提交的表单数据,我们还需要再添加一个Register action,这两个action的作用是:

  • 一个用来响应Http Get请求: 为action添加HttpGet特性(也可以省略),Get请求通常是用户第一次访问页面时,通过该action初始化空白表单。
  • 一个用来响应Http Post请求:为acton方法添加HttpPost特性,Html.BeginForm()创建的窗体默认被浏览器处理为Post请求。这个版本的action方法负责接收提交的表单数据并进行相应处理。
       [HttpGet]
        public ActionResult Register()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Register(UserInfo userInfo)
        {
            return View("Complete",userInfo);
        }

2.Model Binding

在上面的post方法中,使用了MVC中一个非常不错的特性---Model Binding,它可以解析传来的数据并将其对应到领域模型的属性。其实这个Model Binding过程是双向的,当创建form数据时,input控件的值是根据与其name对应的model属性来赋值的;反过来,当提交form表单时,通过model binding又可以根据input控件的name属性来为model实体同名的属性赋值,进而提交到post action方法。

五、表单验证

在MVC应用程序中,我们一般把验证添加在model实体而不放在用户界面,这样只要我们在一处定义了验证规则便可以多处生效。ASP.NET MVC总具体实现方式是:使用System.ComponentModel.DataAnnotations 中定义的特性,将其声明在model属性作为验证规则就可以生效了。

1. Model实体添加验证规则

Model Validation Code
using System.ComponentModel.DataAnnotations;
namespace DamifanliMvc3.Models
{
    /// <summary>
    
/// 注册用户实体
    
/// </summary>
    public class UserInfo
    {
        /// <summary>
        
/// 自动编号
        
/// </summary>
        public int Id { getset; }

        /// <summary>
        
/// 用户名
        
/// </summary>
        [Required(ErrorMessage = "请输入用户名")]
       [RegularExpression("^[a-zA-Z][a-zA-Z0-9]{2,14}$", ErrorMessage = "请输入3-15位字母或数字")]
        public string UserName { getset; }

        /// <summary>
        
/// 密码(明文简单示例)
        
/// </summary>
        [Required(ErrorMessage = "请输入密码")]
        public string Password { getset; }

        /// <summary>
        
/// qq号码
        
/// </summary>
        [Required(ErrorMessage = "请输入QQ号码")]
        [RegularExpression("[1-9][0-9]{4,}",ErrorMessage = "请输入正确的qq号码")]
        public string QQ { getset; }

        /// <summary>
        
/// 邮箱地址
        
/// </summary>
        [Required(ErrorMessage = "请输入邮箱地址")]
        [RegularExpression(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",ErrorMessage = "请输入正确的邮箱地址")]
        public string Email { getset; }
    }
}

2.ModelState.IsValid

我们可以在Controller中使用ModelState.IsValid来检验是否存在验证问题。

public ActionResult Register(UserInfo userInfo)
        {
            if(ModelState.IsValid)
            {
                return View("Complete", userInfo);   //Complete Action后续创建
            }
            return View();
        }

3.错误提示

当用户输入不符合规则时,我们可以在view中使用Html.ValidationSummary()来提示用户。

@using(Html.BeginForm())
{
@Html.ValidationSummary()
    <p>用户名:@Html.TextBoxFor(m=>m.UserName)</p>
    ……

}

该方法会在页面中放置一系列隐藏的li,MVC可以令这些位置可见并显示model验证属性中定义的错误信息,如下图所示。点击注册按钮时该页面不会进行跳转,直到所有输入都符合规范为止。值得庆幸的是,提交失败时之前填写的数据仍然会保留在页面中。

image

 

查看页面源代码:

<p>
用户名:<input class="input-validation-error" data-val="true" data-val-regex="请输入3-15位字母或数字" data-val-regex-pattern="^[a-zA-Z][a-zA-Z0-9]{2,14}$" data-val-required="请输入用户名" id="UserName" name="UserName" type="text" value="" />
</p>

六、注册完成页面

1.添加Complete View:

在前面的post提交的Register中,我们已经给出了注册完成时要跳转的目标”Complete”,并且传递了变量userInfo,接下来我们添加一个强类型UserInfo类型的View。

image

修改代码如下:

@model DamifanliMvc3.Models.UserInfo
@{
    ViewBag.Title = "注册完成";
}
<h2>注册完成</h2>
<p>
    恭喜,您已注册成功,请妥善保管注册信息:<br/>
    账号:@Model.UserName<br/>
    QQ:@Model.QQ<br/>
    Email:@Model.Email<br/>
    大米返利网祝您购物愉快!
</p>

 

2. 发送邮件通知


在展示Complete View的同时,我们使用WebMail类来发送通知邮件。

@{
    try
    {
        WebMail.SmtpServer = "smtp.sina.com";
        WebMail.SmtpPort = 587;
        WebMail.EnableSsl = true;
        WebMail.UserName = "CathyChen";
        WebMail.Password = "damifanli";
        WebMail.From = "cathychen@sina.com";
        WebMail.Send(@Model.Email,"成功注册大米返利网",@Model.UserName+",您已成功注册大米返利网,祝您购物愉快!");
    }
    catch
    {
        @:抱歉,通知邮件发送失败!
    }
}

小结:

到这里,今天的学习基本结束了。当然了这只是一个简单的示例,实际使用中还有很多可以改进的地方,比如将发送邮件功能放在单独的模块中调用而不是将代码块嵌在View中,以便重复使用;另外,这里的错误处理使用的try…catch,其实可以跳转到单独的错误页面。

posted on 2012-10-10 15:34 BoyXiao 阅读(303) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

留言簿(42)

最新评论

阅读排行榜

评论排行榜