Asp.Net MVC4.0 官方教程 入门指南之六--查看Edit方法和Edit视图

在这节课程中,你将查看为影片控制器生成的方法和视图。

运行程序,在浏览器中访问/Movies。鼠标悬停在影片列表某条记录的Edit链接上方,会看到链接类似于http://localhost:5279/Movies/Edit/1

Edit的链接是由Views\Movies\Index.cshtml文件中的Html.ActionLink方法生成的,如下所示:@Html.ActionLink("Edit", "Edit", new { id=item.ID }) 

Html对象是System.Web.Mvc.WebViewPage基类暴露出来的一个属性,作为助手来使用。助手的ActionLink方法令动态生成与控制器中的方法关联的HTML超链接变得容易。ActionLink的第一个参数是显示的文本(例如,编辑)。第二个参数是要调用的方法名。最后一个参数是生成的匿名路由数据对象(在这个例子中,是指值为1的ID)。

在上面生成的链接地址是http://localhost:5279/Movies/Edit/1。默认路由(在App_Start\RouteConfig.cs中创建)解析URL的模式为{controller}/{action}/{id}。因此,ASP.NET将http://localhost:5279/Movies/Edit/1转换成Movies控制器的Edit方法的请求,并携带一个值为1参数ID。在App_Start\RouteConfig.cs文件中查看以下代码:

复制代码
publicclass RouteConfig    {        publicstaticvoid 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 }            );        }    }
复制代码

你也可以使用查询字符串来传递方法参数。例如,http://localhost:5279/Movies/Edit?ID=1同样传递值为1的ID参数给Movies控制器的Edit方法。

打开Movies控制器文件。两个Edit方法如下所示:

复制代码
//// GET: /Movies/Edit/5public ActionResult Edit(int id = 0)        {            Movie movie = db.Movies.Find(id);            if (movie == null)            {                return HttpNotFound();            }            return View(movie);        }        //// POST: /Movies/Edit/5        [HttpPost]        public ActionResult Edit(Movie movie)        {            if (ModelState.IsValid)            {                db.Entry(movie).State = EntityState.Modified;                db.SaveChanges();                return RedirectToAction("Index");            }            return View(movie);        }
复制代码

注意第二个Edit方法前面加了HttpPost属性。该属性指定这个重载的Edit方法仅在接受Post请求时被调用。你可以将HttpGet属性应用在第一个Edit方法,但那不是必须的,因为它是默认的。(我们将为HttpGet方法隐性地指定HttpGet属性)。
HttpGet属性的Edit方法获取影片ID参数,使用Entity Framework的Find方法查找影片,并返回选中的影片给Edit视图。当Edit方法被调用时没有参数传入时,ID参数指定0作为默认值。当无法找到影片时,返回HttpNotFound。当脚手架系统创建Edit视图时,查看Movie类并为该类的每个属性创建和元素。下面的例子展示了生成的Edit视图:

复制代码
@model MvcMovie.Models.Movie@{    ViewBag.Title = "Edit";}

Edit

@using (Html.BeginForm()) { @Html.ValidationSummary(true)
Movie @Html.HiddenFor(model =< model.ID)
class= " editor-label "< @Html.LabelFor(model =< model.Name)
class= " editor-field "< @Html.EditorFor(model =< model.Name) @Html.ValidationMessageFor(model =< model.Name)
class= " editor-label "< @Html.LabelFor(model =< model.Genra)
class= " editor-field "< @Html.EditorFor(model =< model.Genra) @Html.ValidationMessageFor(model =< model.Genra)
class= " editor-label "< @Html.LabelFor(model =< model.Price)
class= " editor-field "< @Html.EditorFor(model =< model.Price) @Html.ValidationMessageFor(model =< model.Price)
class= " editor-label "< @Html.LabelFor(model =< model.Date)
class= " editor-field "< @Html.EditorFor(model =< model.Date) @Html.ValidationMessageFor(model =< model.Date)

"</span>submit" value="Save" /<

}
@Html.ActionLink( " Back to List ", " Index " )
@section Scripts { @Scripts.Render("~/bundles/jqueryval")}
复制代码

注意该视图模板在文件顶部有@model MvcMovie.Models.Movie语句--指定了视图期望的模型是Movie类型。
脚手架代码使用几个Helper方法来生成流式的Html标记。Html.LabelFor显示字段名称(片名、价格、风格等)。Html.EditorFor生成元素。Html.ValidationMessageFor展示与属性关联的验证信息。
运行程序,导航到/Movies 地址。点击Edit超链接。在浏览器中查看页面源代码。表单元素的Html源码如下所示:

复制代码
DOCTYPE html<< span>html lang="zh"<< span>head<< span>meta http-equiv="Content-Type" content="text/html; charset=utf-8"/<< span>meta charset="utf-8"/<< span>title<Edit - 电影应用程序</>title<< span>link href="/favicon.ico" rel="shortcut icon" type="image/x-icon"/<< span>meta name="viewport" content="width=device-width"/<< span>link href="/Content/site.css" rel="stylesheet"/<< span>script src="/Scripts/modernizr-2.5.3.js"<</>script<</>head<< span>body<< span>header<< span>div class="content-wrapper"<< span>div class="float-left"<< span>p class="site-title"<< span>a href="/"<MVC 电影</>a<</>p<</>div<< span>div class="float-right"<< span>section id="login"<< span>ul<< span>li<< span>a href="/Account/Register" id="registerLink"<注册</>a<</>li<< span>li<< span>a href="/Account/Login" id="loginLink"<登录</>a<</>li<</>ul<</>section<< span>nav<< span>ul id="menu"<< span>li<< span>a href="/"<主页</>a<</>li<< span>li<< span>a href="/Home/About"<关于</>a<</>li<< span>li<< span>a href="/Home/Contact"<联系方式</>a<</>li<</>ul<</>nav<</>div<</>div<</>header<< span>div id="body"<< span>section class="content-wrapper main-content clear-fix"<< span>h2<Edit</>h2<< span>form action="/Movies/Edit/1" method="post"<< span>fieldset<< span>legend<Movie</>legend<< span>input data-val="true" data-val-number="字段 ID 必须是一个数字。" data-val-required="ID 字段是必需的。" id="ID" name="ID" type="hidden" value="1"/<< span>div class="editor-label"<< span>label for="Name"<Name</>label<</>div<< span>div class="editor-field"<< span>input class="text-box single-line" id="Name" name="Name" type="text" value="少年派的奇幻之旅"/<< span>span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"<</>span<</>div<< span>div class="editor-label"<< span>label for="Genra"<Genra</>label<</>div<< span>div class="editor-field"<< span>input class="text-box single-line" id="Genra" name="Genra" type="text" value="冒险"/<< span>span class="field-validation-valid" data-valmsg-for="Genra" data-valmsg-replace="true"<</>span<</>div<< span>div class="editor-label"<< span>label for="Price"<Price</>label<</>div<< span>div class="editor-field"<< span>input class="text-box single-line" data-val="true" data-val-number="字段 Price 必须是一个数字。" data-val-required="Price 字段是必需的。" id="Price" name="Price" type="text" value="60.96"/<< span>span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"<</>span<</>div<< span>div class="editor-label"<< span>label for="Date"<Date</>label<</>div<< span>div class="editor-field"<< span>input class="text-box single-line" data-val="true" data-val-date="字段 Date 必须是日期。" data-val-required="Date 字段是必需的。" id="Date" name="Date" type="datetime" value="2012/12/5 0:00:00"/<< span>span class="field-validation-valid" data-valmsg-for="Date" data-valmsg-replace="true"<</>span<</>div<< span>p<< span>input type="submit" value="Save"/<</>p<</>fieldset<</>form<< span>div<< span>a href="/Movies"<Back to List</>a<</>div<</>section<</>div<< span>footer<< span>div class="content-wrapper"<< span>div class="float-left"<< span>p<© 2012 - 我的 ASP.NET MVC 应用程序</>p<</>div<</>div<</>footer<< span>script src="/Scripts/jquery-1.7.1.js"<</>script<< span>script src="/Scripts/jquery.unobtrusive-ajax.js"<</>script<< span>script src="/Scripts/jquery.validate.js"<</>script<< span>script src="/Scripts/jquery.validate.unobtrusive.js"<</>script<</>body<</>html<
复制代码
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>


包含元素的HTML

元素的action属性设置为/Movies/Edit ,方法为post。点击Edit按钮,表单数据将被post到服务器。
处理Post请求

下面列表显示了处理HttpPost请求版本的Edit方法</p>
复制代码
//// POST: /Movies/Edit/5        [HttpPost]        public ActionResult Edit(Movie movie)        {            if (ModelState.IsValid)            {                db.Entry(movie).State = EntityState.Modified;                db.SaveChanges();                return RedirectToAction("Index");            }            return View(movie);        }
复制代码

ASP.NET MVC模型绑定机制获取post表单值,创建Movie对象作为参数。ModelState.IsValid方法验证表单提交的数据可以用来修改(编辑或更新)Movie对象。如果数据有效,则影片数据将被保存到MovieDbContext实例集合中。新的影片数据在调用MovieDbContext的SaveChanges时保存到数据库。保存完数据后,代码引导用户到MoviesController 的Index方法,在那展示包括刚刚修改的影片在内的影片集合。
如果post的数据无效,将在表单中重新显示。Edit.cshtml视图模板中的Html.ValidationMessageFor助手负责显示错误信息。

MVC验证中所有属性验证成功ModelState.IsValid等于true,只要有一个验证不成功ModelState.IsValid就等于false 所以我们可以通过该属性来判断数据的有效性,但有时在数据验证时有时我们不需要验证所有的数据,比如登录时只需要验证用户名及密码格式是否输入正确即可。
使用以下方法可以排除要验证的字段:
ModelState.Remove("Email");不验证Email
这样Email这个字段就不会被验证了,Email验证不通过ModelState.IsValid的值仍然是true

译者注:原文在该部分有大量篇幅提示在非英语母语国家,使用逗号来替代货币中的小数点,来实现JQuery正确验证数据的目的,与主题无关,在此做删节处理,有兴趣的可以阅读英文原文。

所有的HttpGet方法遵循相似的模式。获取一个movie对象(或者对象集合,比如在Index例子中),从模型传递到视图。Create方法传递空对象给Create视图。创建、编辑、删除或者修改数据等所有操作放在HttpPost重载方法中。在HttpGet方法中修改数据存在安全隐患,详细信息请查看ASP.NET MVC Tip #46 – Don’t use Delete Links because they create Security Holes。在Get方法中修改数据同样违法Http最佳实践以及Rest模式(指定Get请求不应当变更你的应用程序状态)。换句话说,执行Get操作应该是一个不影响以及不会修改此前数据的安全操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值