转:ASP.NET MVC利用TryUpdateModel来做资料更新 (一)

时间:2023-03-09 06:20:44
转:ASP.NET MVC利用TryUpdateModel来做资料更新 (一)

前言
有使用 ASP.NET MVC 的朋友们一定多多少少有听过 TryUpdateModel,之前就看了很多有关它的文章,但在专案实务上都未曾实际使用过,而 TryUpdateModel 不仅能利用 Metadata 来做栏位验证确保资料正确性,也可以指定更新的条件或是指定某几个栏位不更新,这几天刚好有时间就写了简单的范例,来看看它到底有什么神奇魔力吧。

说明
首先我们先定义一个 Model 如下:

转:ASP.NET MVC利用TryUpdateModel来做资料更新 (一)
 

一般透过 TryUpdateModel 来做资料更新,最简单的写法如下 :

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int Id)
{
Product product = db.Product.Where(p => p.Id.Equals(Id)).FirstOrDefault();
if (TryUpdateModel(product, new string[] { "Name", "Ename", "ModifyUid" }))
{
db.SaveChanges();
return RedirectToAction("Index");
}
return View(product);
}

在 TryUpdateModel 里的第一个参数为要被更新的资料,而第二个参数则是我们要细节的资料,这时候可能会有个疑问,那它细节的资料是从哪边而来的?「其实就跟 Model Binding 的机制很像,TryUpdateModel 会透过你从表单回传的资料,只要名称一样就会自己系节上去啰。」

所以透过上面的程式码,只会更新 Name、Ename、ModifyUid 这三个栏位,其他栏位的资料是不会做更新的。www.it165.net

但如果今天我们页面上的栏位有十几二十个的的话,若使用上面的方法光打栏位名称可能就会花费许多时间!
此时我们可以利用 FormCollection 来接收 View 传来的资料来做栏位更新,所以可以改成以下写法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int Id, FormCollection FromValue)
{
Product product = db.Product.Where(p => p.Id.Equals(Id)).FirstOrDefault();
if (TryUpdateModel(product, FromValue.AllKeys) && ModelState.IsValid)
{
db.SaveChanges();
return RedirectToAction("Index");
}
return View(product);
}

但问题又来了,一般情况下总是会有某些栏位是不希望使用者去做更新的,则透过 TryUpdateModel 的多载来达到排除栏位的效果,如下:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int Id, FormCollection FromValue)
{
Product product = db.Product.Where(p => p.Id.Equals(Id)).FirstOrDefault();
if (TryUpdateModel(product, "", FromValue.AllKeys, new string[] { "ModifyUid" }))
{
db.SaveChanges();
return RedirectToAction("Index");
}
return View(product);
}

如上面的程式片段,我们可以排除更新 ModifyUid 的栏位。

总结
TryUpdateModel 拥有了10个多载的方法,所以它可以应用的范围也非常广,但在使用上也有需要注意的地方,像是其第一个多载方法就存在着「安全性问题」,因为预设是接收 View 所传来的资料来做资料系结,只要是符合的栏位就会直接写入 Model 中,所以当你有某些栏位是不想给使用者更新时,请务必设定「白名单」或「黑名单」!