1. 从页面到action
讲述controller与View之间的具体运作关系
在上次添加的名为Movie的Model内添加
下面我们尝试为该model内的属性添加attribute
具体修改如下:
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属性,修改属性名称 [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; } } }
运行项目后,页面中相关属性变化如下:
这样的改变是如何生成的?
观察我们Views下的Movies目录下的index文件,其中改变为:
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID })
这是razor引擎的一个方法,参数依次为:按钮名称,Action名称,参数(这里参数为id)
能自动进行跳转的原因是系统已经默认配置了路由:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
接下来观察Movies的Controller中的Edit是怎么工作的
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 // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 // 详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkId=317598。
// 使用Post方式
[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);
2.解析Edit的Action和View
回到MoviesController文件
// GET: Movies/Edit/5 public ActionResult Edit(int? id) { // 判断是否为空,为空则返回错误信息 if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } // 数据库中获取Movies表并查找相应id Movie movie = db.Movies.Find(id); if (movie == null) { // 查找不到指定id的项目 return HttpNotFound(); } // 返回数据给view进行使用 return View(movie); } // POST: Movies/Edit/5 // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 // 详细信息,请参阅 https://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); }
也可查看其相应的view(cshtml文件)
3.解析Details的Action和View
只有get方式,主要是用来获取详细信息的。
public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); }
4.解析Delete的Action和View
// GET: Movies/Delete/5 public ActionResult Delete(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/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Movie movie = db.Movies.Find(id); db.Movies.Remove(movie); db.SaveChanges(); return RedirectToAction("Index"); }