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 条评论
登录 后参与评论

相关文章

来自专栏编码小白

ofbiz中FreeMarkerWorker的makeConfiguration方法

            这个方法是说明了为什么在ftl中可以使用一些java方法             1.代码展示 public static Confi...

3367
来自专栏Golang语言社区

[Go 语言社区] Golang架构底层函数图片保存-原创

PS: StrBase64Data 传入的需要去除: “data:image/png;base64,”字段 // 保存磁盘的数据的图片处理函数 func...

2699
来自专栏葡萄城控件技术团队

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

在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图。但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上...

25810
来自专栏Vamei实验室

来玩Play框架04 表单

表单(form)是最常见的从客户往服务器传递数据的方式。Play框架提供了一些工具。它们可以从表单中提取数据,验证提交数据的合法性,或者在视图中显示表单。我先来...

17610
来自专栏葡萄城控件技术团队

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

在本节中,您将创建一个新的MoviesController类,并在这个Controller类里编写代码来取得电影数据,并使用视图模板将数据展示在浏览器里。 在开...

1985
来自专栏葡萄城控件技术团队

在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

背景 在前一篇文章《【初学者指南】在ASP.NET MVC 5中创建GridView》中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类...

1998
来自专栏计算机视觉

failed to allocate **M (** bytes) from device: CUDA_ERROR_OUT_OF_MEMORY,错误原因及解决方案

config = tf.ConfigProto(allow_soft_placement=True) gpu_options = tf.GPUOptions(...

1183
来自专栏liulun

ASP.NET Core教程【二】从保存数据看Razor Page的特有属性与服务端验证

前文索引: ASP.NET Core教程【一】关于Razor Page的知识 在layout.cshtml文件中,我们可以看到如下代码: <a asp-page...

2845
来自专栏柠檬先生

html5 离线存储 地理信息与本地存储

搭建离线应用程序   ①服务器设置头信息 :     AddType text/cache-manifest .manifest   ② html标签...

1849
来自专栏Java成神之路

Java微信公众平台开发_07_JSSDK图片上传

(2)对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成...

601

扫描关注云+社区