ASP.NET MVC学习笔记06编辑方法和编辑视图

上一篇中,说到了MVC生成的Index方法,和Details方法,现在来说一下自动生成的方法和视图,应该怎么的来进行编辑。

优化日期显示

在这之前,先对前面的代码进行优化,使得发布日期属性(ReleaseDate)看上去更好。打开Models/Movies.cs参考下图进行修改。

上图中用到了DataAnnotations。Display属性指明要显示的字段的名 称(在本例中“Release Date”来代替“ReleaseDate”)。DataType属性用于指定类型的数据,在本例它是一个日期,所以不会显示存放在该字段时间详情。DisplayFormat属性在Chrome浏览器里有一个bug:呈现的日期格式不正确。

调试,浏览,然后点击一个条目,进入编辑。

如上图所示,Edit(编辑)链接是由Views\ Movies\Index.cshtml 视图中Html.ActionLink方法所生成的.

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

Html对象是一个 Helper, 以属性的形式在System.Web.Mvc.WebViewPage基类上公开。ActionLink是一个帮助方法(Helper),便于动态生成指向Controller中操作方法 的HTML 超链接链接。ActionLink方法的第一个参数是想要呈现的链接文本 (例如,<a>Edit Me</a>)。第二个参数是要调用的操作方法的名称(在本例中, Edit方法)。最后一个参数是一个匿名对象 (anonymous object),用来生成路由数据 (在上图中,ID 为1 的)。

因此跳转的链接为,http://localhost:50948/movies/Edit/1,默认的路由 (在 App_Start\RouteConfig.cs中设定)使用的 URL 匹配模式为: {controller}/{action}/{id}。因 此,ASP.NET 将 http://localhost:xxxxx/Movies/Edit/4转化到 Movies 控制器中 Edit操作 方法,参数 ID等于1 的请求。所以,输入http://localhost:50948/movies/Edit?id=1同样会把参数ID 等于1的请求传给控制器的Edit方法。

控制器的Edit方法

再来看看MoviesController中的Edit的两个方法。

注意,第二个Edit操作方法的上面有HttpPost属性。此属性指定了Edit方法的重载,此方法仅 被POST 请求所调用。可以将HttpGet属性应用于第一个编辑方法,但不需要这样,因为它是默认的属性。(操作方法会被隐式的指定为HttpGet属性,从而作为 HttpGet 方法。) 绑定(Bind)属性是另一个重要安全机制,可以防止黑客攻击(从over-posting数据到模型)。应该只包含在bind属性属性,本教程中使用的简单模型,模型中绑定所有数据。ValidateAntiForgeryToken属性是用来防止伪造的请求,并配对@Html.AntiForgeryToken()文件 ( Views\Movies\Edit.cshtml ),如下图所示,部分在Edit View文件:

@Html.AntiForgeryToken() 生成隐藏的窗体, 防伪令牌必须匹配Movies控制器的 Edit 方法。在教程 XSRF/CSRF Prevention in MVC,你可以读到更多关于跨站点请求伪造 (也称为XSRF或CSRF)。 HttpGet Edit方法会获取电影ID参数、 查找影片使用 Entity Framework 的Find 方法,并返回 到选定影片的编辑视图。如果不带参数调用Edit 方法,ID 参数被指定为默认值 零。如果找不到一 部电影,则返回 HttpNotFound 。当 scaffolding自动创建编辑视图时,它会查看Movie类并为 类的每个属性创建用于 Render的<label><input>的元素。

注意,视图模板在文件的顶部有 @model MvcMovie.Models.Movie的声明,这将指定视 图期望的模型类型为` Movie。

scaffolded自动生成的代码,使用了Helper 方法的几种简化的 HTML 标记 。Html.LabelFor 用来显示字段的名称(”Title”、”ReleaseDate”、”Genre”或”Price”)。Html.EditorFor用来呈现 HTML <input>元素。Html.ValidationMessageFor用来 显示与该属性相关联的任何验证消息。视图模板在文件的顶部有 @model MvcMovie.Models.Movie的声明,这将指定视 图期望的模型类型为 Movie。

处理 POST 请求

回看前面的Eidt的Post方法。

ASP.NET MVC model binder接收form所post的数据,并转换所接收的 Movie请求数据从而创建一个Movie对象。ModelState.IsValid方法用于验证提交的表单数据是否可用于修改(编辑或更新)一个Movie对象。如果数据是有效的电影数据,将保存到数据库的Movies集合(MovieDBContext 实例)。通过调用MovieDBContext的SaveChanges方法,新的电影数据会被保存到数据库。数据保存之后,代码会把用户重定向到 MoviesController类的Index操作方法,页面将显示电影列表,同时包括刚刚所做的更新。

一旦客户端验证确定某个字段的值是无效的,将显示出现错误消息。如果禁用 JavaScript,则不会有客户端验证,但服务器将检测回传的值是无效的,而且将重新显示 表单中的值与错误消息。在本教程的后面,我们验证更详细的审查。 Edit.cshtml 视图模板 中的 Html.ValidationMessageFor Helper将用来显示相应的错误消息。

所有 HttpGet方法遵循类似的模式。他们得到一个电影对象(或对象列表中,如本案例的 Index),并把模型数据传递给视图。Create方法传递一个空的影片对象给Create视图。 所有的 create, edit, delete方法,或其他的方法: 用HttpPost重载的方法修改数据。修改 数据在HTTP GET方法, 存在安全风险。在HTTP GET方法中修改数据也违反HTTP 的最佳实践和REST模式架构,指明GET请求不应该改变你的应用程序的状态。换句话说,执行GET操作应该是一个安全,操作,无任何副作用,不会修改你的持久化数据。

按照电影流派添加搜索

首先,如果之前添加了 HttpPost 的Index方法,请立即删除它。

下面,通过一些列的修改,来让用户可以通过流派来搜索电影。先从Controller中的index方法开始。

这个版本的 Index方法将接受一个附加的 movieGenre参数。前几行的代码会创建一个 List对象来保存数据库中的电影流派。

下面的代码是从数据库中检索所有流派的 LINQ 查询:

var GenreQry = from d in db.Movies  
                   orderby d.Genre  
                   select d.Genre;

该代码使用泛型 List集合的 AddRange方法将所有不同的流派,添加到集合中的。(使 用 Distinct修饰符,不会添加重复的流派 – 例如,在我们的示例中添加了两次喜剧)。

该代码然后在ViewBag对象中存储了流派的数据列表。的SelectList对象在ViewBag作 为存储类数据(这样的电影流派),然后在下拉列表框中的数据访问类别,是一个典型的MVC applications的方法。 下面的代码演示如何检查 movieGenre参数。如果它不是空的,代码进一步指定了所查询的电影流派。

if (!string.IsNullOrEmpty(movieGenre)) 
 { 
    movies = movies.Where(x => x.Genre == movieGenre); 
 }

如前所述,查询数据不会在数据库上运行,直到电影列表迭代结束(恰发生在View, Index方法返回后)。

注意:这个地方用到了LinQ的知识,如果对LinQ不太了解的,可以查阅官方文档.

Index视图添加标记

Views\Movies\Index.cshtml文件中,添加Html.DropDownList辅助方法,在TextBox前。完成的代码如下图所示:

下面的代码:

@Html.DropDownList("movieGenre", "All")

ViewBag中,”movieGenre“ 参考作为key在DropDownList中搜索 IEnumerable<SelectListItem > .

ViewBag填入的操作方法: 参数“All”提供的项列表中的预先选择的。如我们使用下面的代码:

@Html.DropDownList("movieGenre", "Comedy")

在我们的数据库中,我们拥有与“喜剧”流派的电影,“喜剧”在下拉列表中将预先选 择。因为我们没有一个电影流派“All”,也没有“All”的 SelectList,所以当我们post back后不做任何选择,movieGenre查询字符串值是空的。 运行应用程序并浏览 /Movies/Index。尝试搜索流派,来检索信息。

在本篇中,创建了一个搜索的方法和视图,使用它,用户可以通过电影标题和流派来搜 索。在下一篇中,将看到如何添加一个属性到 Movie model,和如何添加一个初始值设定项值,它会自动创建一个测试数据库。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CaiRui

Python Flask-web表单

Flask-WTF扩展可以把处理web表单的过程变成一种愉悦的体验。 ? 一、跨站请求伪造保护 默认情况下,Flask-WTF能够保护所有表单免受跨站请求伪造的...

3169
来自专栏DeveWork

【译】WordPress 中的50个过滤器(3):第11-20个过滤器

本文为系列第三篇,原文:50 Filters of WordPress: Filters 11-20 原文地址 不多说,直接进入正题。 本系列文章翻译自tut...

2036
来自专栏阮一峰的网络日志

JavaScript与有限状态机

有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物。 ? 简单说,它有三个特征:   * 状态总数(stat...

3487
来自专栏zcqshine's blog

springboot 获取form-data里的 file 文件小结

5886
来自专栏不止是前端

TS+React+Router+Mobx+Koa打造全栈应用

4507
来自专栏Java帮帮-微信公众号-技术文章全总结

web前端之锋利的jQuery八:jQuery插件的使用(表单验证、表单提交)

插件也称扩展,是一种遵循一定规范的应用程序接口编写出来的程序。 1.jQuery表单验证插件-Validation: 最常使用JavaScript的场合就是表...

3085
来自专栏jmeter高手高高手

Jmeter(三十一)_dummy sampler模拟数据驱动

之前写过一篇数据驱动的文章 数据驱动测试 ,但是内容过于简单,有些关键的地方没有写明白。这两天参照了一下官方文档,重新整理了一篇数据驱动测试!

2003
来自专栏大内老A

[CORS:跨域资源共享] 同源策略与JSONP

Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分。“同源策略”限制了JavaSc...

1959
来自专栏大学生计算机视觉学习DeepLearning

VS下如何建立一个新的MFC程序 网络编程 课设 基于C++ MFC 连接数据库 小应用 小项目浅析展示

1973
来自专栏逸鹏说道

Python3 与 C# 并发编程之~ 线程篇2

其实以前的 Linux中是没有线程这个概念的, Windows程序员经常使用线程,这一看~方便啊,然后可能是当时程序员偷懒了,就把进程模块改了改(这就是为什么之...

1684

扫码关注云+社区