• 跟小静学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,其实可以跳转到单独的错误页面。

  • 相关阅读:
    数组去重的方法
    ES5-ES8 数组拥有的方法
    常用的git操作命令
    vue中使用vue-echarts
    js的深复制与浅复制
    express 4.x 搭建Node项目框架
    网页布局分类
    shadow---实例
    animate动画解析
    3d------正方体
  • 原文地址:https://www.cnblogs.com/janes/p/2717874.html
Copyright © 2020-2023  润新知