[转载]Asp.net MVC3.0 入门指南 6 审视编辑方法和视图 – cn_大斌哥 – 博客园.
在这一节中,您将审视movie控制器生成的响应方法和视图。然后您将添加
一个自定义搜索页面。
运行程序并通过在URL追加/Moives浏览movie控制器。把鼠标悬停在Edit
链接上,看看它执行的URL.
Edit的链接由视图Views\Movies\Index.cshtml 的Html.ActionLink方法生成。
@Html.ActionLink("Edit", "Edit", new { id=item.ID })
Html对象是一个助手,它是WebViewPage
基类暴露的属性。助手的ActionLink方法可以很容易的生成
HTML超级链接,它指向控制器的响应方法。ActionLink的第一个参数超级链接的文本呈现(比如:
<a>Edit Me</a>),第二个参数是要调用的响应方法的名称,最后一个参数生成路由数据的匿名对象
(anonymous object,这里指ID=4)。
您可以使用查询字符串(query string)传递参数给响应方法。比如URL
http://localhost:xxxxx/Movies/Edit?ID=4传递ID=4给Movies控制器的Edit方法。
打开Movies控制器。有两个Edit方法,如下所示:
// // GET: /Movies/Edit/5 public ActionResult Edit(int id) { Movie movie = db.Movies.Find(id); 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
请求调用。您也可以给第一个Edit方法采用HttpGet属性,但是这不是必须的,应为
方法默认为HttpGet(响应方法隐含的了HttpGet属性将被认为是HttpGet方法)。
HttpGet方法将电影的ID作为参数,并使用实体框架的Find方法查找电影,然后返回被找
到的电影给视图模板。当架构体系创建编辑模板是,它检查Movie类并为每个属性生成
代码去呈现<label><input>元素。下面的代码展示了自动生成的Edit视图模板:
注意第二个Edit方法前面是HttpPost属性。它表明这个重载的Edit方法只能被POST 请求调用。您也可以给第一个Edit方法采用HttpGet属性,但是这不是必须的,应为 方法默认为HttpGet(响应方法隐含的了HttpGet属性将被认为是HttpGet方法)。 HttpGet方法将电影的ID作为参数,并使用实体框架的Find方法查找电影,然后返回被找 到的电影给视图模板。当架构体系创建编辑模板是,它检查Movie类并为每个属性生成 代码去呈现<label><input />元素。下面的代码展示了自动生成的Edit视图模板:</label> @model MvcMovie.Models.Movie @{ ViewBag.Title = "Edit"; } <h2>Edit</h2> <script src="@Url.Content(" type="text/javascript"></script> <script src="@Url.Content(" type="text/javascript"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Movie</legend>@Html.HiddenFor(model => model.ID) <div class="editor-label">@Html.LabelFor(model => model.Title)</div> <div class="editor-field">@Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title)</div> <div class="editor-label">@Html.LabelFor(model => model.ReleaseDate)</div> <div class="editor-field">@Html.EditorFor(model => model.ReleaseDate) @Html.ValidationMessageFor(model => model.ReleaseDate)</div> <div class="editor-label">@Html.LabelFor(model => model.Genre)</div> <div class="editor-field">@Html.EditorFor(model => model.Genre) @Html.ValidationMessageFor(model => model.Genre)</div> <div class="editor-label">@Html.LabelFor(model => model.Price)</div> <div class="editor-field">@Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price)</div> <input type="submit" value="Save" /></fieldset> } <div>@Html.ActionLink("Back to List", "Index")</div>
form>中的<input>元素别用来回传页面到电影的编辑地址/Movies/Edit。
当点击Edit按钮时,页面的数据被回传到服务器。
处理POST请求
由架构体系生成的属性为HttpGet的Edit方法没有检查传给它的ID的有效性。
如果用户删除URL的ID片段,错误信息如下所示:
用户还可以传递一个不存在的ID,比如:http://localhost:xxxxx/Movies/Edit/1234.您可以给
HttpGet Edit方法做两点修改来限制URL。首先,把ID参数改为默认值为0 (id不是必须传递)。
您也可以在回传电影对象给视图模板之前,检查Find方法是否真正的找到了电影信息。
public ActionResult Edit(int id = 0) { Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); }
如果没有找到,HttpNotFound方法被调用。
所有的HttpGet方法都遵循类似的模式。它们获取一个电影对象(在Index中返回对象列表),
然后传递模型给视图。Create方法传递一个空电影对象给Create视图。所有的方法(创建、
编辑、删除)都有一个HttpPost的重载方法。
在HTTP GET方法中修改数据存在安全风险,在博客
ASP.NET MVC Tip #46 – Don’t use Delete Links because they create Security Holes
中有描述。
在HTTP GET方法中修改数据违反了HTTP的最佳实践
和
REST架构模式(其中规定,
GET请求不应改变应用程序状态)。换句话,执行GET操作应该是一个无副
作用的安全操作。
下一节:ASP.NET MVC3.0 入门指南 7 展示查找页面
原文网址:http://www.asp.net/mvc/tutorials/getting-started-with-mvc3-part6-cs