zoukankan      html  css  js  c++  java
  • MVC3学习第七章 排山倒海第三变----利用MVC3实现数据验证以及完成用户数据的编辑

    本章学习内容

    1.用DataAnnotations实现模型验证

    2.实现用户数据的编辑实现(ActionResult.ViewResult)

    1.用DataAnnotations实现模型验证

    上一章中我们已经完成了用的添加和列表操作,对于一个完整的增删改查来说我们还缺少编辑和删除,这在本章后续会完成。我们先来回顾一下前文的添加,输入数据,入库保存,很简单的操作,有没有发现有什么不足的地方?或许聪明的你已经发现了,我们虽然保存了用户信息,但明显信息验证不够健壮,甚至连最起码的是否必须输入都没有验证,或许你想到了这时候可以去页面写验证的js,又或者你觉得此时缺少了webform下的RequiredFieldValidator和CustomValidator使得mvc的验证不太方便,其实,mvc的验证远比这些验证方式更加灵活好用,接下来我们就为我们的UserInfo加入表单验证。

    首先,罗列一下我们要达到的验证效果:

    1).所有数据必须输入,除了邮箱以外;

    2).密码应是3-8个字符

    3).邮箱和电话的格式应该正确

    先就这么多吧,没有用到的验证我们之后也会讲到,打开Models/UserInfo,修改完整代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    
    namespace MyShopTest.Models
    {
        public class UserInfo
        {
            [ScaffoldColumn(false)]
            public int Id { get; set; }
            [Display(Name="用户名")]
            [Required(ErrorMessage="必须输入用户名!")]
            public string UserName { get; set; }
            [Display(Name = "密码")]
            [Required(ErrorMessage = "必须输入密码!")]
            [StringLength(8, MinimumLength = 3, ErrorMessage = "密码长度必须是3到8个字符之间")]
            public string UserPwd { get; set; }
            [Display(Name = "电话")]
            [Required(ErrorMessage = "必须输入电话!")]
            [RegularExpression(@"((d{11})|^((d{7,8})|(d{4}|d{3})-(d{7,8})|(d{4}|d{3})-(d{7,8})-(d{4}|d{3}|d{2}|d{1})|(d{7,8})-(d{4}|d{3}|d{2}|d{1}))$)",ErrorMessage="电话格式不正确")]
            public string Phone { get; set; }
            [Display(Name = "邮箱")]
            [RegularExpression(@"w+([-+.']w+)*@w+([-.]w+)*.w+([-.]w+)*", ErrorMessage = "邮箱格式不正确")]
            public string Email { get; set; }
            private DateTime addTime;
            [Display(Name="注册时间")]
            [Required()]
            public DateTime AddTime
            {
                get
                {
                    if (addTime == null)
                    {
                        return DateTime.Now;
                    }
                    return addTime;
                }
                set { addTime = value; }
            }
        }
    }

    我们来解释一下这些属性头部的验证代码:

    • Required 必须 – 表示这个属性是必须提供内容的字段
    • Display 显示名 – 定义表单字段的提示名称(也可以写成DisplayName("要显示的名字"))
    • StringLength 字符串长度 – 定义字符串类型的属性的最大长度
    • Range 范围 – 为数字类型的属性提供最大值和最小值,此处没有用到
    • Bind 绑定 – 列出在将请求参数绑定到模型的时候,包含和不包含的字段,此处没有用到,一般写在实体某些类名的头部,格式如[Bind(Exclude = "OrderId")]
    • ScaffoldColumn 支架列 - 在编辑表单的时候,需要隐藏起来的的字符,主键会自动隐藏,这里可以不用为Id写,此处只是为了理解
    • RegularExpression,自定义正则验证

     重新编译项目,修改我们的Create视图,以便应用这些验证,修改UserInfo/Create.cshtml,完整代码如下:

    @model MyShopTest.Models.UserInfo
    @{
        ViewBag.Title = "添加用户";
    }
    <h2>
        添加用户</h2>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    @using (Html.BeginForm())
    {
        <fieldset>
            <legend>添加用户</legend>
             <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserPwd)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(model => model.UserPwd)
                @Html.ValidationMessageFor(model => model.UserPwd)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Phone)
                @Html.ValidationMessageFor(model => model.Phone)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Email)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Email)
                @Html.ValidationMessageFor(model => model.Email)
                <input type="hidden" name="AddTime" value="@DateTime.Now"/>
            </div>
            <p>
                <input type="submit" value="添加" />
            </p>
        </fieldset>
    }
    <div>
        <a href="Index">返回列表</a>
    </div>

    我们来解释一下这个修改后的Create视图我们不认识的标签,

    @Html.LabelFor(model => model.UserName)等类似的代码

    之前我们直接写的是“用户名”,“密码”等文字,现在换成了这一段代码, 它的意思是使用model.UserName的Display信息显示在此处,再看看我们的UserName属性的代码

            [Display(Name="用户名")]
            [Required(ErrorMessage="必须输入用户名!")]
            public string UserName { get; set; }

    此时使用@Html.LabelFor(model => model.UserName)就会显示用户名

    再来看下一段代码:

    @Html.EditorFor(model => model.UserName)

    如同上一个的解释,不过此处的意思是输出一个model.UserName的文本框,之前我们是手写的文本框,此处也罗列一下:

    <input type="text" name="UserName" />

    两者实现的功能基本一样,之所以说基本,是因为还有不一样的,原因是使用@Html.EditorFor配合紧接着要说的代码段,可以实现自动验证

     @Html.ValidationMessageFor(model => model.UserPwd)

    这段代码就是执行我们的那些验证规则并且输出验证信息了,请注意此时只有使用@Html.EditFor或者其他@Html.输出的html标签,才能搭配输出验证信息,如果是我们自己手写的文本框则不可以。

    好了,我们已经编写好了验证规则,我们来看一下效果,重新编译项目,在首页点击用户管理

    报错了,恭喜你,修改差不多成功了。为什么会报错呢?因为我们修改了实体规则,这和数据库里现有的字段规则不符,所以报错了,要解决这个错误我们有两种方法,一是手动修改数据库字段的规则和实体一致,二是重新根据此实体来创建数据库。为了简便测试,我们直接删除掉数据库里现有的MyShop数据库,让系统重新创建,当然如果有很多数据时我们进行此操作很明显很危险,不过目前只是测试,所以不用考虑。

    重新运行程序,进入用户管理

    点击添加用户,输入一些错误信息,点击添加,看一下验证效果:

    我们期望的验证已经基本都达到了,添加符合验证的信息,点击添加

    操作成功。

    2.实现用户数据的编辑实现

    现在我们来实现用户的修改功能

    还是一一样,我们先来创建对应的用户修改的Action,修改UserInfoController.cs的完整代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MyShopTest.Models;
    using System.Data;
    namespace MyShopTest.Controllers
    {
        public class UserInfoController : Controller
        {
            //数据访问
            private MyShopDataEntities db = new MyShopDataEntities();
            /// <summary>
            /// 用户列表Action
            /// </summary>
            /// <returns></returns>
            public ActionResult Index()
            {
                var users = db.UserInfos.ToList();
                return View(users);
            }
            /// <summary>
            /// 添加用户页面展示
            /// </summary>
            /// <returns></returns>
            public ActionResult Create()
            {
                return View();
            }
            /// <summary>
            /// 添加用户处理
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult Create(UserInfo user)
            {
                db.UserInfos.Add(user);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            /// <summary>
            /// 编辑用户页面展示
            /// </summary>
            /// <returns></returns>
            public ActionResult Edit(int id)
            {
                var user = db.UserInfos.Find(id);
                return View(user);
            }
            /// <summary>
            /// 编辑用户处理
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult Edit(UserInfo user)
            {
                try
                {
                    if (ModelState.IsValid)
                    {
                        db.Entry(user).State = EntityState.Modified;
                        db.SaveChanges();
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                catch (Exception)
                {
    
                    ModelState.AddModelError("", "更改失败");
                }
    
                return View(user);
            }
    
        }
    }

    我们来解析一下新增Edit代码的新知识,db.UserInfos.Find(id)查找某个Id的用户,之后返回给视图,作用是在视图页面赋值;

    ModelState.IsValid是用来验证当前模型实例是否有效的,说的更通俗一点,就是是否通过了字段合法性检查的验证,通过了则返回true,否则返回false;db.Entry(user).State = EntityState.Modified;意思是表名当前对象已经更新,但是还没保存,db.SaveChanges();执行数据库更改,如果一切操作顺利,则返回列表页,如果没有通过验证,我们来抛出一个异常,如果期间更新出错,也进入异常处理,异常处理里ModelState.AddModelError("", "更改失败");就是为当前模型添加错误信息,除了异常则将当前模型返回此Action对应的视图,视图里如果有 @Html.ValidationSummary(true)语句,则会输出错误信息,这在稍后的修改视图里大家就可以看到。

    现在添加Edit视图,修改完整代码如下

    @model MyShopTest.Models.UserInfo
    
    @{
        ViewBag.Title = "用户编辑";
    }
    
    <h2>用户编辑</h2>
    
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>用户编辑</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserPwd)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(model => model.UserPwd)
                @Html.ValidationMessageFor(model => model.UserPwd)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Phone)
                @Html.ValidationMessageFor(model => model.Phone)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Email)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Email)
                @Html.ValidationMessageFor(model => model.Email)
            </div>
    
            <p>
                <input type="submit" value="修改" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("返回列表", "Index")
    </div>

     代码应该都说过了,没有新知识, @Html.ValidationSummary(true)是用来显示Model错误信息的。

    除了@Html.ActionLink,在此也解释一下,@Html.ActionLink是用来创建链接的,它也有很多重载的方法,简单说明几个:

    一 Html.ActionLink("linkText","actionName")
    该重载的第一个参数是该链接要显示的文字,第二个参数是对应的控制器的方法,
    默认控制器为当前页面的控制器,如果当前页面的控制器为Products,则 Html.ActionLink("detail","Detail")
    则会生成 <a href="/Products/Detail">all</a>

    二 Html.ActionLink("linkText","actionName","controlName")
    该重载比第一个重载多了一个参数,他指定了控制器的名称,
    如Html.ActionLink("detail","Detail","Products")则会生成
    <a href="Products/Detail">all</a>

    三 Html.ActionLik("linkText","actionName",routeValues)
    routeValue可以向action传递参数,如Html.ActionLink("detail","Detail",new { id=1})
    会生成 <a href="Products/Detail/1">detail</a>,
    此处假设当前的控制器是Products.

    详细请参考http://blog.csdn.net/jingmeifeng/article/details/7792151

    现在我们在列表页加上编辑链接,修改Index.cshtml完整代码如下:

    @model IEnumerable<MyShopTest.Models.UserInfo>
    @{
        ViewBag.Title = "用户列表";
    }
    <h2>
        用户列表</h2>
    <p>
        <a href="/UserInfo/Create">添加用户</a>
    </p>
    <table>
        <tr>
            <th>
                用户名
            </th>
            <th>
                电话
            </th>
            <th>
                邮箱
            </th>
            <th>
                注册时间
            </th>
            <th>
                操作
            </th>
        </tr>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @item.UserName
                </td>
                <td>
                    @item.Phone
                </td>
                <td>
                    @item.Email
                </td>
                <td>
                    @item.AddTime
                </td>
                <td>
                    @Html.ActionLink("编辑", "Edit", new { id=item.Id})
                </td>
            </tr>
        }
    </table>

    重新运行项目,用户管理,点击编辑,

    结果如下:

    修改任意数据,点击修改:

     提示错误信息,错误原因是更新时获取不到Id,我们的编辑页面还缺少一个保存当前修改信息的Id的隐藏域。加入下面的隐藏域代码到Edit.cshtml,修改后的完整代码是:

    @model MyShopTest.Models.UserInfo
    
    @{
        ViewBag.Title = "用户编辑";
    }
    
    <h2>用户编辑</h2>
    
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>用户编辑</legend>
    
            @Html.HiddenFor(model => model.Id)
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserPwd)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(model => model.UserPwd)
                @Html.ValidationMessageFor(model => model.UserPwd)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Phone)
                @Html.ValidationMessageFor(model => model.Phone)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Email)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Email)
                @Html.ValidationMessageFor(model => model.Email)
                
            </div>
            @Html.HiddenFor(model => model.AddTime)
          
    
            <p>
                <input type="submit" value="修改" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("返回列表", "Index")
    </div>

    不用生成,直接刷新页面,重新修改数据提交

    提交后结果

     用户编辑完成

  • 相关阅读:
    【JZOJ4876】【NOIP2016提高A组集训第10场11.8】基因突变
    【JZOJ4869】【NOIP2016提高A组集训第9场11.7】平均数
    【JZOJ4868】【NOIP2016提高A组集训第9场11.7】Simple
    【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块
    【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
    【JZOJ4859】【NOIP2016提高A组集训第7场11.4】连锁店
    【JZOJ4359】【GDKOI2016】魔卡少女
    【JZOJ4848】【GDOI2017模拟11.3】永恒的契约
    【JZOJ4855】【NOIP2016提高A组集训第6场11.3】荷花池塘
    Java编程的逻辑 (16)
  • 原文地址:https://www.cnblogs.com/hswh/p/3151615.html
Copyright © 2011-2022 走看看