在asp.net MVC 应用程序, 表单提交的数据通过模型绑定将数据从View传递到控制器中。使用模型绑定显然比Request.Form["Price"] ,Decimal.Parse(Request.Form["Price"] )还需要手动类型转换要要方便很多。
模型绑定有两种,隐式绑定和显式绑定。
1、隐式模型绑定。先将表单值转化为CLR 类型,然后以表单字段name名称,value值参数传递到Action中。为了防止过度提交,使用Bind(Include)属性接受白名单,Bind(Exclude="")属性拒绝黑名单。
// POST: Movie/Create
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
if (ModelState.IsValid)
{
db.Movies.Add(movie); //将实体的跟踪状态设置为 EntityState.Added;如果是在编辑操作中, 需要手动设置 EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
2、显式绑定 使用TryUpdateModel 和UpdateModel 显式绑定,它自动将数据库上下文对象的跟踪的实体状态设置为EnrityState.Modified。还可以通过设定参数来指定绑定的字段,两者的区别 是如果 绑定失败,前者不会抛出一个异常,后者会引发异常。
[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var studentToUpdate = db.Students.Find(id);
if (TryUpdateModel(studentToUpdate, "", new string[] { "LastName", "FirstMidName", "EnrollmentDate" }))
{
try
{
//已不需要下面的语句,来设置数据库上下文跟踪实体的状态了,已自动设置跟踪状态的EntityState.Modified标记
// db.Entry(studentToUpdate).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
catch(DataException /* dex*/)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "不能保存更改,重试一次,如果问题仍然存在,请与系统管理员联系");
}
}
return View(studentToUpdate);
}