MVC5学习系列——详解编辑操作

本文是MVC5学习系列的一部分,详细介绍了编辑操作,并结合Bootstrap进行页面美化。首先修改了列表页面,移除英文并添加Bootstrap样式。接着展示了修改后的Index.cshtml页面和Movie模型类,探讨了Display、DataType和DisplayFormat属性的用途。然后分析了MoviesController中的Edit方法,讨论了Bind和ValidateAntiForgeryToken属性的安全机制。最后,通过实例展示了编辑电影、POST请求的处理,并提到了客户端验证的可能性,尤其是AngularJS的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MVC5学习笔记,其实就是敲了一遍官网代码,官网地址:http://www.asp.net/mvc             

接着上一篇 MVC5学习系列——从控制器访问模型的数据(添加、修改、删除),这次我们详细说一下编辑操作,不过在这之前先修改一下列表页面。先将页面中的英文处理掉,还有就是如果你创建了一个不是空的MVC程序,那么程序中默认集成了Bootstrap ,这里我们也自己动手添加Bootstrap 样式。按照自动生成的MVC非空程序模板,我们也把样式文件放到根目录的Content文件夹中。

看一下修改之后的Index.cshtml页面:

@model IEnumerable<DDZ.MVC5Test.Models.Movie>
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>我的电影</title>
    <link href="~/Content/Bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
   <div class="container">
       <p>
           @Html.ActionLink("添加电影", "Create")
       </p>
       <table class="table">
           <tr>
               <th>
                   @Html.DisplayNameFor(model => model.Title)
               </th>
               <th>
                   @Html.DisplayNameFor(model => model.ReleaseDate)
               </th>
               <th>
                   @Html.DisplayNameFor(model => model.Genre)
               </th>
               <th>
                   @Html.DisplayNameFor(model => model.Price)
               </th>
               <th></th>
           </tr>
           @foreach (var item in Model)
           {
               <tr>
                   <td>
                       @Html.DisplayFor(modelItem => item.Title)
                   </td>
                   <td>
                       @Html.DisplayFor(modelItem => item.ReleaseDate)
                   </td>
                   <td>
                       @Html.DisplayFor(modelItem => item.Genre)
                   </td>
                   <td>
                       @Html.DisplayFor(modelItem => item.Price)
                   </td>
                   <td>
                       @Html.ActionLink("编辑", "Edit", new { id = item.ID }) |
                       @Html.ActionLink("详情", "Details", new { id = item.ID }) |
                       @Html.ActionLink("删除", "Delete", new { id = item.ID })
                   </td>
               </tr>
           }
       </table>
   </div>
</body>
</html>
还有修改之后的Edit.cshtml页面:

@model DDZ.MVC5Test.Models.Movie
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>我的电影—编辑</title>
    <link href="~/Content/Bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
   <div class="container">
       @using (Html.BeginForm())
       {
           @Html.AntiForgeryToken()

           <div class="form-horizontal">
               <h4>我的电影—编辑</h4>
               <hr />
               @Html.ValidationSummary(true, "", new { @class = "text-danger" })
               @Html.HiddenFor(model => model.ID)

               <div class="form-group">
                   @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
                   <div class="col-md-10">
                       @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                       @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
                   </div>
               </div>

               <div class="form-group">
                   @Html.LabelFor(model => model.ReleaseDate, htmlAttributes: new { @class = "control-label col-md-2" })
                   <div class="col-md-10">
                       @Html.EditorFor(model => model.ReleaseDate, new { htmlAttributes = new { @class = "form-control" } })
                       @Html.ValidationMessageFor(model => model.ReleaseDate, "", new { @class = "text-danger" })
                   </div>
               </div>

               <div class="form-group">
                   @Html.LabelFor(model => model.Genre, htmlAttributes: new { @class = "control-label col-md-2" })
                   <div class="col-md-10">
                       @Html.EditorFor(model => model.Genre, new { htmlAttributes = new { @class = "form-control" } })
                       @Html.ValidationMessageFor(model => model.Genre, "", new { @class = "text-danger" })
                   </div>
               </div>

               <div class="form-group">
                   @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
                   <div class="col-md-10">
                       @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                       @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
                   </div>
               </div>

               <div class="form-group">
                   <div class="col-md-offset-2 col-md-10">
                       <input type="submit" value="保  存" class="btn btn-default" />
                   </div>
               </div>
           </div>
       }
       <div>
           @Html.ActionLink("返回列表", "Index")
       </div>
   </div>
</body>
</html>

此外,按照官网的步骤,修改一下Movie模型类:

public class Movie
    {
        public int ID { get; set; }
        [Display(Name = "电影名称")]
        public string Title { get; set; }
        [Display(Name = "发行日期")]
     [DataType(DataType.Date)]
     [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
     public DateTime ReleaseDate { get; set; }
        [Display(Name = "电影类型")]
        public string Genre { get; set; }
        [Display(Name = "电影售价")]
        public decimal Price { get; set; }
    }

别忘了这个:using System.ComponentModel.DataAnnotations;

官方注释:The Display attribute specifies what to display for the name of a field (in this case "发行日期" instead of "ReleaseDate"). The DataType attribute specifies the type of the data, in this case it's a date, so the time information stored in the field is not displayed. The DisplayFormat attribute is needed for a bug in the Chrome browser that renders date formats incorrectly.

下面调试一下:


你可以点击“编辑”还可以在浏览器中输入:http://localhost:56544/Movies/Edit?id=1

好像是比之前好看多了,多谢Bootstrap。

下面看一下控制器MoviesController中自动生成的Edit方法:

// GET: Movies/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Movie movie = db.Movies.Find(id);
            if (movie == null)
            {
                return HttpNotFound();
            }
            return View(movie);
        }

        // POST: Movies/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "ID,Title,ReleaseDate,Genre,Price")] Movie movie)
        {
            if (ModelState.IsValid)
            {
                db.Entry(movie).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(movie);
        }
很明显,第一个方法应该是页面加载获取电影详情用的,首先判断主键id是否为空。然后是
 Movie movie = db.Movies.Find(id);

我们先不管db.Movies是如何获取电影列表的,以后在慢慢研究吧!而第二个方法是保存用的。

官方解释:The Bind attribute is another important security mechanism that keeps hackers from over-posting data to your model.The ValidateAntiForgeryToken attribute is used to prevent forgery of a request and is paired up with @Html.AntiForgeryToken() in the edit view file (Views\Movies\Edit.cshtml).  

Edit.cshtml页面代码上面已给出,自己寻找@Html.AntiForgeryToken()。

官方注释:@Html.AntiForgeryToken() generates a hidden form anti-forgery token that must match in the Edit method of the Movies controller.

The ValidateAntiForgeryToken attribute validates the XSRF token generated by the @Html.AntiForgeryToken() call in the view.

先添加一个电影:速度与激情2。我们看一下截图:



点击保存之后,我们用Fiddler 来看一个这个POST请求:





哎,菜啊!没有理解@Html.AntiForgeryToken()和[ValidateAntiForgeryToken]的深意。上面的验证应该是来自服务器端的,现在我们完全可以在客户端做这些处理。毕竟Jquery很牛逼,还有新兴的AngularJS等。这篇就写到这里吧!客户端验证就不写了。个人还是喜欢AngularJS,改天试一下吧!谢谢!


2015-12-26 修改

这里我们利用超链接看看如何传递多个参数,先看看自动生成的代码:

  @Html.ActionLink("编辑", "Edit", new { id = item.ID,otherP = new { StuName = "qq"})
再看看浏览器解析之后的代码:

<a href="/Movies/Edit/6">编辑</a>
现在我们试着添加多个参数,这里我直接添加了一个匿名对象:

@Html.ActionLink("编辑", "Edit", new { id = item.ID, otherP = new { StuName = "qq", StuAge = "1" } })
再看看浏览器解析之后的代码:

<a href="/Movies/Edit/6?otherP=%7B%20StuName%20%3D%20qq%2C%20StuAge%20%3D%201%20%7D">编辑</a>
哈哈,被编码了。不管了,直接调试看看什么情况:



嘿嘿,不错。传个对象都没问题!但是之后测试 传非匿名对象(DDZ.MVC5Test.Controllers.Student)就不可以了,泛型List< DDZ.MVC5Test.Controllers.Student>就更不用提了(我也是试了)。估计是弄到URL上不好弄!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值