【MVC5】7.检查Edit方法和Edit视图

在本节中,您将检查所生成的Edit操作方法和movie
controller的视图。但首先需要采取一个简短的更改,使发布日期看起来更好。打开Models\Movie.cs文件并修改为下面代码:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

你也可以让日期文化像这样:

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

我们将在下一个教程介绍DataAnnotationsDisplay属性指定为一个字段的名称显示(在这种情况下,"Release
Date"而不是"ReleaseDate")。DataType属性指定的数据类型,在这种情况下,这是一个日期,所以字段中存储的时间信息不显示。 DisplayFormat属性属性是在浏览器中的一个错误,使日期格式不正确的需要。

运行应用程序并浏览到电影控制器。将鼠标指针放在一个Edit链接上,查看它链接到的网址。

Edit链接通过在视图的 Html.ActionLink方法生成Views\Movies\Index.cshtml 视图:

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) 

HTML对象是一个使用system.web.mvc.webviewpage基类属性的辅助工具。其中的ActionLink方法便于动态生成HTML超链接控制器动作方法链接。ActionLink方法的第一个参数是提供链接文本(例如,<a>编辑我</a>)。第二个参数是调用的动作方法的名称(比如这里的 Edit动作)。最后一个参数是一个匿名对象,生成路由数据(比如这里的身份证号
4)。

在以往的影像显示生成的链接是http://localhost:1234/Movies/Edit/4。默认路由(在App_Start\RouteConfig.cs生成)以URL模式 {controller}/{action}/{id}。因此,ASP.NET将http://localhost:1234/Movies/Edit/4变成要求Edit动作方法的控制器的参数与电影ID等于4。从App_Start\RouteConfig.cs文件检查下面的代码。MapRoute方法到正确的控制器和动作方法的HTTP请求路由和供应可选的id参数。MapRoute方法也由 HtmlHelpers 使用如连接产生了控制器使用的URL,动作方法和任何路由数据。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index",
            id = UrlParameter.Optional }
    );
}

您也可以使用查询字符串传递动作方法参数。例如,URL的http://localhost:1234/Movies/Edit?ID=3也通过了参数标识为3的电影控制器的Edit动作方法。

打开电影控制器。两个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
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see 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);
}

注意第二个编辑动作方法是之前HttpPost属性。这个属性指定过载的编辑方法只能调用POST请求。你可以应用HttpGet属性于第一个Edit方法,但这不是必要的,因为它是缺省值。(我们会参考操作方法隐式分配HttpGet属性HttpGet方法。)Bind属性是另一个重要的安全机制,防止黑客over-posting数据模型。您应该只包含属性绑定属性,你想改变,你可以读到overposting
overposting安全注意和绑定属性。在本教程中使用的简单的模型,我们将绑定在模型中所有的数据。ValidateAntiForgeryToken属性是用来防止伪造请求和配对与@Html.AntiForgeryToken()在编辑视图文件(Views\Movies\Edit.cshtml),部分如下所示:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

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

@Html.AntiForgeryToken()生成一个隐藏表单种防伪标记,必须匹配在电影的Edit方法的控制器。你可以阅读更多关于跨站点请求伪造(也称为XSRF或CSRF)在我的教程XSRF / MVC CSRF预防。

HttpGet编辑方法接受电影ID参数,查找电影使用实体框架发现方法,并返回所选电影编辑视图。如果一部电影不能被发现,HttpNotFound返回。当脚手架系统创建编辑视图时,它检查了电影类和创建代码呈现<标记>和<输入>元素的每个属性类。下面的例子显示了生成的编辑视图的visual studio脚手架系统:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.ReleaseDate, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ReleaseDate)
                @Html.ValidationMessageFor(model => model.ReleaseDate)
            </div>
        </div>
        @*Genre and Price removed for brevity.*@
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

注意,视图模板有一个@ model MvcMovie.Models。电影声明顶部的文件——这指定视图预计模型的视图模板类型的电影。

搭建的代码使用一些辅助方法来简化HTML标记。Html.EditorFor辅助显示字段的名称(“标题”、“ReleaseDate”,“流派”,或“价格”)。Html。EditorFor助手呈现HTML
<input>元素。Html.ValidationMessageFor 辅助显示任何验证消息相关的财产。

运行应用程序并导航到 /Movies网址。点击一个Edit链接。在浏览器中,视图页面的源代码的HTML表单元素如下所示。

<form action="/movies/Edit/4" method="post">
   <input name="__RequestVerificationToken" type="hidden" value="UxY6bkQyJCXO3Kn5AXg-6TXxOj6yVBi9tghHaQ5Lq_qwKvcojNXEEfcbn-FGh_0vuw4tS_BRk7QQQHlJp8AP4_X4orVNoQnp2cd8kXhykS01" />  <fieldset class="form-horizontal">
      <legend>Movie</legend>

      <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" />

      <div class="control-group">
         <label class="control-label" for="Title">Title</label>
         <div class="controls">
            <input class="text-box single-line" id="Title" name="Title" type="text" value="GhostBusters" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Title" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="ReleaseDate">Release Date</label>
         <div class="controls">
            <input class="text-box single-line" data-val="true" data-val-date="The field Release Date must be a date." data-val-required="The Release Date field is required." id="ReleaseDate" name="ReleaseDate" type="date" value="1/1/1984" />
            <span class="field-validation-valid help-inline" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Genre">Genre</label>
         <div class="controls">
            <input class="text-box single-line" id="Genre" name="Genre" type="text" value="Comedy" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="control-group">
         <label class="control-label" for="Price">Price</label>
         <div class="controls">
            <input class="text-box single-line" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" type="text" value="7.99" />
            <span class="field-validation-valid help-inline" data-valmsg-for="Price" data-valmsg-replace="true"></span>
         </div>
      </div>

      <div class="form-actions no-color">
         <input type="submit" value="Save" class="btn" />
      </div>
   </fieldset>
</form>

<input>元素是在HTML <form>元素的动作属性设置为post /Movies/Edit URL。表单数据将被张贴到服务器时,单击Save按钮。第二行显示了隐藏XSRF
@Html.AntiForgeryToken()调用生成的令牌。

处理POST请求

下面的清单显示了HttpPost版本的Edit操作方法。

[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);
}

ValidateAntiForgeryToken属性验证XSRF @Html.AntiForgeryToken()调用生成的令牌在视图中。

ASP.NET
MVC
模型绑定器将发布表单值并创建一个电影作为电影参数传递的对象。ModelState.IsValid方法验证表单中提交的数据可以用来修改(编辑或更新)电影对象。如果数据是有效的,电影数据保存到电影db(MovieDBContext实例)的集合。新电影的数据保存到数据库中通过调用MovieDBContext中的SaveChanges方法。在保存数据,代码将用户重定向到索引MoviesController类的动作方法,它显示电影集合,包括相应的改变。

一旦客户端验证确定一个字段的值是无效的,显示一个错误消息。如果禁用JavaScript,您不会有客户端验证但服务器会检测到这个值是无效的,和表单的值将被显示错误消息。后在本教程中我们更详细地检查验证。

Html.ValidationMessageFor协助在Edit.cshtml视图模板中显示适当的错误消息。

所有HttpGet方法遵循一个类似的模式。他们获得电影对象(或对象的列表,在Index的情况下),并通过模型的视图。Create方法传递一个空的电影对象来创建视图。所有的方法创建、编辑、删除或者修改数据HttpPost过载的方法。修改数据在一个HTTP
GET方法是一个安全风险,如博客条目所述 ASP.NET
MVC Tip #46 – Don’t use Delete Links because they create Security Holes
,因为他们创造了安全漏洞。修改数据获得方法也违反了HTTP的最佳实践和其他建筑模式,它指定,GET请求不应改变应用程序的状态。换句话说,执行一个GET操作应该是一个安全的操作,没有副作用,不会修改您保存数据。

时间: 2024-10-14 14:05:59

【MVC5】7.检查Edit方法和Edit视图的相关文章

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解 在本章中,我们研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打开Models\Movie.cs 文件.先添加一个引用: <span style="font-size:14px;">using System.ComponentModel.DataAnnotations;</span> 然后在Movie类中添加以下代码: [Display(

ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

原文:ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view) 在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie.cs文件,并添加高亮行如下所示: using System; using System.ComponentModel.DataAnnotations; using System.Data.

ASP.NET Core 中文文档 第二章 指南(4.10)检查自动生成的Detail方法和Delete方

原文 Examining the Details and Delete methods 作者 Rick Anderson 翻译 谢炀(Kiler) 校对 许登洋(Seay).姚阿勇(Mr.Yao) 打开 Movie 控制器并查看 Details 方法: // GET: Movies/Details/5 public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } var mo

[转]ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie.cs文件,并添加高亮行如下所示: using System; using System.ComponentModel.DataAnnotations; using System.Data.Entity; namespace MvcMovie.Models { public class Movie

Win8系统语音识别使用方法和xp内置语音输入软件安装

下面介绍两款现在主流系统的一些特殊功能,语音输入,也许你还没有正式使用这些功能,但是系统中既然有这项功能就有着它存在的意义,这节就讲下Win8与XP的语音识别功能的使用方法. 之一<Win8>启动语音识别功能 首先,用户需要准备一部笔记本电脑和一个麦克风.Win8语音识别程序能够支持任何类型的麦克风,甚至包括内置在用户笔记本中的扩音器.不过,微软表示,价格在20美元左右的麦克风效果最佳. 激活语音识别功能最简单方法就是打开"开始"(Start)界面,输入"语音&q

详解equals()方法和hashCode()方法

前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方法,都可以被重写(overwrite). 本文介绍了2种方法在使用和重写时,一些需要注意的问题. 一.equal()方法 Object类中equals()方法实现如下: public boolean equals(Object obj) { return (this == obj); } 通过该实现

Android中的Sqlite中的onCreate方法和onUpgrade方法的执行时机

今天在做数据库升级的时候,遇到一个问题,就是onCreate方法和onUpgrade方法的执行时机的问题,这个当时在操作的时候,没有弄清楚,很是迷糊,所以写代码的时候出现了很多的问题,所以没办法就去扒源代码看了.不过在此之前我讲解过一篇关于数据库升级的文章,但是那里没有详细的讲解一下这两个方法的执行时机,所以这里就在单独说一下 关于数据库升级的文章:http://blog.csdn.net/jiangwei0910410003/article/details/39670813 不多说,下面直接进

序列化和持久化 merge方法和saveOrUpdate方法

merge方法和saveOrUpdate方法的区别 merge方法是把我们提供的对象转变为托管状态的对象:而saveOrUpdate则是把我们提供的对象变成一个持久化对象:说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取. 使用merge方法修改时如果两次修改的值没有变,它只会执行select而不会进行update.

wait方法和sleep方法的区别

一.概念.原理.区别 Java中的多线程是一种抢占式的机制而不是分时机制.线程主要有以下几种状态:可运行,运行,阻塞,死亡.抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行. 当有多个线程访问共享数据的时候,就需要对线程进行同步.线程中的几个主要方法的比较: Thread类的方法:sleep(),yield()等 Object的方法:wait()和notify()等 每个对象都有一个机锁来控制同步访问.Synchronized关键字可以和对象的机锁交互,来实现线程的同步. 由于s