[ASP.NET MVC][筆記] 利用 TryUpdateModel 來做資料更新 (一)


有使用 ASP.NET MVC 的朋友們一定多多少少有聽過 TryUpdateModel,之前就看了很多有關它的文章,但在專案實務上都未曾實際使用過,而 TryUpdateModel 不僅能利用 Metadata 來做欄位驗證確保資料正確性,也可以指定更新的條件或是指定某幾個欄位不更新,這幾天剛好有時間就寫了簡單的範例,來看看它到底有什麼神奇魔力吧。

前言

有使用 ASP.NET MVC 的朋友們一定多多少少有聽過 TryUpdateModel,之前就看了很多有關它的文章,但在專案實務上都未曾實際使用過,而 TryUpdateModel 不僅能利用 Metadata 來做欄位驗證確保資料正確性,也可以指定更新的條件或是指定某幾個欄位不更新,這幾天剛好有時間就寫了簡單的範例,來看看它到底有什麼神奇魔力吧。

說明

首先我們先定義一個 Model 如下:

一般透過 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 這三個欄位,其他欄位的資料是不會做更新的。


但如果今天我們頁面上的欄位有十幾二十個的的話,若使用上面的方法光打欄位名稱可能就會花費許多時間!
此時我們可以利用 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 中,所以當你有某些欄位是不想給使用者更新時,請務必設定「白名單」或「黑名單」!


參考資料

新手發文,如有錯誤煩請告知,感謝。
如果喜歡我的文章請按推薦,有任何問題歡迎下面留言~~~

 

 

簽名:

學習這條路很廣,喜歡什麼技術不重要,重要的是你肯花時間去學習