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

21 篇文章 0 订阅

在本节中,您会检查生成Edit 操作方法和视图为电影控制器。但是,首先将会采取短的声明,让发布日期看起来更好。打开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; }

在接下来的教程中,我们将DataAnnotations 。显示属性指定要显示的字段 (在本例中"发布日期"而不是"ReleaseDate") 的名称。数据类型属性指定的数据类型,在这种情况下它是一个日期,所以时间信息存储在不显示字段。DisplayFormat属性被需要在 Chrome 浏览器呈现的日期格式不正确的 bug。

运行应用程序并浏览到Movies控制器。将鼠标指针悬停在编辑链接,看到它链接到的 URL。

EditLink_sm

编辑链接是由 Html.ActionLink方法在Views\Movies\Index.cshtml视图中生成的︰

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

Html.ActionLink

Html对象是使用上System.Web.Mvc.WebViewPage基类的属性公开的帮手。帮助器的 ActionLink 方法,便于动态生成 HTML 超链接链接到控制器上的操作方法。ActionLink方法的第一个参数是要呈现的链接文本 (例如, <a>Edit Me</a>)。第二个参数是要 (在这种情况下,Edit行动) 调用的操作方法的名称。最后一个参数是匿名对象生成路由数据 (在本例中,ID 为 4 的)。

上图中所示的生成的链接是http://localhost:1234/Movies/Edit/4默认的路由 (在App_Start\RouteConfig.cs建立) 采用 URL 模式{controller}/{action}/{id}因此,ASP.NET 会将http://localhost:1234/Movies/Edit/4转化为对Movies 控制器中参数为ID等于 4 的Edit操作方法的请求。检查App_Start\RouteConfig.cs文件中的以下代码。MapRoute方法用于将 HTTP 请求路由到正确的控制器和操作方法,提供可选的 ID 参数。MapRoute方法也由HtmlHelpers ActionLink 用于生成给定控制器、 操作方法和任何路由数据的 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也将参数ID=3传递给Movies控制器的Edit操作方法。

EditQueryString

打开Movies控制器。两个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);
}

通知的第二个Edit操作方法的前面 HttpPost属性。此属性指定,过载的Edit方法可以调用只为 POST 请求。您可以将 HttpGet属性应用于第一种编辑方法,但这是不必要的因为它是默认值。(我们将引用他们作为HttpGet方法隐式地分配HttpGet属性的操作方法)。绑定属性是过度张贴到您的模型数据可防止黑客的另一个重要的安全机制。只应在您想要更改绑定属性中包含属性。你可以阅读有关 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() Movies 控制器的Edit 方法生成一个隐藏的窗体防伪标记,必须匹配。你可以阅读更多关于跨站点请求伪造 (也被称为 XSRF 或 CSRF) 在我的教程在 MVC 中 XSRF/CSRF 预防.

HttpGetEdit方法获取电影 ID 参数、 查找电影使用实体框架 Find方法,并返回到编辑视图的选定的影片。如果找不到一部电影,则会返回HttpNotFound 。当脚手架系统创建编辑视图时,它审查Movie类和创建渲染<label><input>元素的每个属性的类的代码。下面的示例显示了由 visual studio 架构体系生成的Edit视图

@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.Movie语句在文件的顶部 — — 这指定视图期望的模型视图模板类型Movie.

搭建的代码使用的帮助器方法的几种简化的 HTML 标记。 Html.LabelFor帮助器将显示的字段 ("标题"、"ReleaseDate"、"流派"或"价格") 的名称。 Html.EditorFor帮助器呈现 HTML <input>元素。 Html.ValidationMessageFor帮助器将显示与该属性关联的任何验证消息。

运行应用程序并定位到/Movies的 URL。单击编辑链接。在浏览器中查看页面的源代码。如下所示的 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>元素是其action的属性设置为发布到/Movies/Edit URL HTML <form>元素中。单击保存按钮时,表单数据将张贴到服务器。第二行显示隐藏的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 模型联编程序取出已发送窗体值,并创建一个Movie作为movie参数传递。ModelState.IsValid方法验证提交表单中的数据可以用于修改 (编辑或更新)Movie对象。如果数据是有效的电影数据保存到Movies集合的db(MovieDBContext instance)。新的电影数据将保存到数据库中,通过调用MovieDBContext SaveChanges方法。保存数据之后, 的代码将用户重定向到Index操作方法的MoviesController类,显示收藏的电影,包括刚刚所做的更改。

只要客户端验证确定某个字段的值不是有效,将显示一条错误消息。如果您禁用 JavaScript,你不会有客户端验证,但服务器将检测到的已过帐的值不是有效的和窗体值将重新显示详细错误消息。稍后在本教程中我们研究中更详细的验证。

Edit.cshtml视图模板 Html.ValidationMessageFor佣工照顾显示相应的错误消息。

abcNotValid

所有HttpGet方法都遵循类似的模式。他们得到电影对象 (或对象的列表,在Index的情况下),并将模型传递给视图。Create方法将空影片对象传递给创建视图。创建、 编辑、 删除或以其他方式修改数据的方法这样做在HttpPost重载的方法。在 HTTP GET 方法中修改数据是安全风险的博客帖子条目中所述ASP.NET MVC 提示 #46 — — 不使用删除链接,因为它们创建安全漏洞在 GET 方法中修改数据也违反了 HTTP 的最佳做法和建筑的其他模式,指定 GET 请求不应更改应用程序的状态。换句话说,执行 GET 操作,应该是没有副作用,不会修改您的持久化的数据的安全操作。

如果您正在使用美国英语的计算机,可以跳过此节并转到下一个教程。您可以下载本教程在这里的全球化版本。对国际化优秀两部分教程,请参见纳迪姆的 ASP.NET MVC 5 国际化.

 
注意要支持 jQuery 验证为非英语区域设置,使用逗号 (",") 为小数点和非美国英语日期格式,您必须包括globalize.js和你具体cultures/globalize.cultures.js文件 (从https://github.com/jquery/globalize ) 和 JavaScript 使用Globalize.parseFloat你可以从 NuGet jQuery 非英语验证。(不要安装全球化如果你使用的英语的语言环境)。
  1. 工具菜单中单击库软件包管理器,,然后单击管理 NuGet 程序包的解决方案.



  2. 在左窗格中,选择在线(见下面的图片)。
  3. 搜索安装的软件包的输入框中,输入全球化。



    单击安装Scripts\jquery.globalize\globalize.js文件将添加到您的项目。Scripts\jquery.globalize\cultures\文件夹将包含许多文化 JavaScript 文件。请注意,它可能需要五分钟才能安装此程序包。
下面的代码演示对 Views\Movies\Edit.cshtml 文件的修改︰
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

<script src="~/Scripts/globalize/globalize.js"></script>
<script src="~/Scripts/globalize/cultures/globalize.culture.@(System.Threading.Thread.CurrentThread.CurrentCulture.Name).js"></script>
<script>
    $.validator.methods.number = function (value, element) {
        return this.optional(element) ||
            !isNaN(Globalize.parseFloat(value));
    }
    $(document).ready(function () {
        Globalize.culture('@(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
    });
</script>
<script>
    jQuery.extend(jQuery.validator.methods, {
        range: function (value, element, param) {
            //Use the Globalization plugin to parse the value
            var val = Globalize.parseFloat(value);
            return this.optional(element) || (
                val >= param[0] && val <= param[1]);
        }
    });
    $.validator.methods.date = function (value, element) {
        return this.optional(element) ||
            Globalize.parseDate(value) ||
            Globalize.parseDate(value, "yyyy-MM-dd");
    }
</script>
}

为了避免重复这段代码在每个编辑视图中的,您可以将其移动到布局文件。若要优化脚本下载,请参阅我的教程捆绑和缩小.

详细信息请参阅ASP.NET MVC 3 国际化ASP.NET MVC 3 国际化-部分 2 (NerdDinner).

作为一种权宜之计,如果您无法验证工作在您的区域设置,您可以强制您使用美国英语的计算机或您可以在您的浏览器中禁用 JavaScript。若要强制您使用美国英语的计算机,可以将全球化元素添加到项目根web.config文件。下面的代码显示设置为美国英语的文化全球化元素。

  <system.web>
    <globalization culture ="en-US" />
    <!--elements removed for clarity-->
  </system.web>
在接下来的教程中,我们将实现搜索功能。

 

-----------------------------------------------------------------------------------------

《ASP.NET MVC 5 入门指南》12篇文章汇总如下:

1. ASP.NET MVC 5 - 入门

2. ASP.NET MVC 5 - 控制器

3. ASP.NET MVC 5 - 视图

4. ASP.NET MVC 5 - 添加一个模型

5. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB

6. ASP.NET MVC 5 - 从控制器访问数据模型

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

8. ASP.NET MVC 5 - 将数据从控制器传递给视图

9. ASP.NET MVC 5 - 添加搜索

10. ASP.NET MVC 5 - 给电影表和模型添加新字段

11. ASP.NET MVC 5 - 给数据模型添加校验器

12. ASP.NET MVC 5 - 查询Details和Delete方法

希望这些文章对感兴趣的朋友有所帮助

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值