ViewModel在MVC3中的应用:实现多字段表格的部分更新

假设我们有这样一张用户表:

 public class F_users

    {

        [Key]

        [Display(Name="用户名:")]

        [Required(ErrorMessage="用户名不能为空")]

       //[Remote("UserIsExist","Login",ErrorMessage="该用户名已经被占用",HttpMethod="post")]

        public virtual string UserName { get; set; }



        [Display(Name = "密码:")]

        [ScaffoldColumn(false)]

        [Required(ErrorMessage = "密码不能为空")]

        [DataType(DataType.Password)]

        [StringLength(50, ErrorMessage = "密码长度不能小于3位", MinimumLength = 3)]

        public virtual string PassWord { get; set; }



        [Display(Name = "确认密码:")]

        [Required(ErrorMessage = "确认密码不能为空")]

        [HiddenInput(DisplayValue = false)]

        [Compare("PassWord", ErrorMessage = "两次密码必须一致")]

        public virtual string RepPassword { get; set; }



        [Display(Name = "密码提示问题:")]

        [Required(ErrorMessage = "密码提示问题不能为空")]

        public virtual int questionID

        {

            get;

            set;

        }

        [Display(Name = "密码提示答案:")]

        [Required(ErrorMessage = "密码提示答案不能为空")]

        public virtual string Answer

        {

            get;

            set;

        }

        [Display(Name = "注册日期:")]

        [DisplayFormat(DataFormatString = "{0:yyyy年MM月dd日}")]

        public virtual System.DateTime RegDate

        {

            get;

            set;

        }

        [Display(Name = "上次登录日期:")]

        [DisplayFormat(DataFormatString = "{0:yyyy年MM月dd日}")]

        public virtual Nullable<System.DateTime> LastLoginTime

        {

            get;

            set;

        }

        [Display(Name = "此次登录日期:")]

        [DisplayFormat(DataFormatString = "{0:yyyy年MM月dd日}")]

        public virtual Nullable<System.DateTime> LonginTime

        {

            get;

            set;

        }

        [Display(Name = "登录次数:")]

        public virtual int LonginCount

        {

            get;

            set;

        }
。。。。。。。。。。。
。。。。。。。。。。
后面还有更多的字段,如邮箱号、手机号、QQ号等。

这样的表格相当复杂,字段也是非常的多。但对这张表格的操作,有些时候只是对部分字段进行操作,而不是全部字段。比如修改邮箱号、修改手机号、修改密码等,找回密码等。

就拿修改密码来说,是一种部分更新,但是在更新的时候,所有Required的字段都得满足条件,验证才能通过,否则ModelState.IsValid将永远是false。有些同学是通过Hidder控件来隐藏不需要在页面上显示的字段,从而通过验证,这样非常麻烦,而且非常不安全。

因此,  这篇文章我拿修改密码举例,说明一下如何利用ViewModel实现多字段实体的部分更新。

一、根据视图需求创建ViewModel

 public class ChangPwdModel

    {

        [Display(Name = "新密码:")]

        [ScaffoldColumn(false)]

        [Required(ErrorMessage = "新密码不能为空")]

        [DataType(DataType.Password)]

        [StringLength(50, ErrorMessage = "密码长度不能小于3位", MinimumLength = 3)]

        public virtual string PassWord { get; set; }



        [Display(Name = "确认新密码:")]

        [Required(ErrorMessage = "确认新密码不能为空")]

        [HiddenInput(DisplayValue = false)]

        [Compare("PassWord", ErrorMessage = "两次密码必须一致")]

        public virtual string RepPassword { get; set; }



        public int ChangePwd(string id)

        {

            Entities db = new Entities();

            F_users fu = db.F_users.Find(id);

            fu.PassWord = this.PassWord;

            fu.RepPassword = this.RepPassword;

            return db.SaveChanges();

        }

    }

注意,有些同学认为有了ViewModel,是不是实体对应的model就不需要了?照样还是需要的,一个表格实体对应一个model,这是基础,无论什么地方都是需要的。ViewModel是建立在model的基础之上的。

二、我们先创建修改密码的视图

@using (Html.BeginForm()) {

    @Html.ValidationSummary(true)

    <fieldset>

        <legend>修改密码</legend>



       <label>原密码:</label><input type="password" name="oldpwd" />

       @Html.ValidationMessage("oldpwd")

       <br />

       @Html.LabelFor(m=>Model.PassWord) 

       @Html.PasswordFor(m=>Model.PassWord)

       @Html.ValidationMessageFor(m=>m.PassWord)

       <br />

       @Html.LabelFor(m=>Model.RepPassword)

       @Html.PasswordFor(m => Model.RepPassword)

       @Html.ValidationMessageFor(m => m.RepPassword)



        <p>

            <input type="submit" value="修改" />

        </p>

    </fieldset>

}

三、根据视图创建控制器

  //修改密码

        public ActionResult ChangePassword()

        {

            return View();



        }

        [HttpPost]

        public ActionResult ChangePassword(ChangPwdModel cp)

        {

            string usn = HttpContext.User.Identity.Name;

            if (ModelState.IsValid)

            {

                string oldPwd = Request.Form["oldpwd"];

                int n = (from c in db.F_users where c.UserName == usn && c.PassWord == oldPwd select c).Count();

                if (n != 1)

                {

                    ModelState.AddModelError("oldpwd", "原密码错误");

                    return View();

                }



                else

                {

                    cp.ChangePwd(usn);

                    FormsAuthentication.SignOut();

                    return RedirectToAction("login", "login");

                }

            }

            else

            {

                ModelState.AddModelError("", "验证没有通过,请修改相应信息后重新提交");

                return View();

            }



        }

 

 

你可能感兴趣的:(Model)