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

前言

第一篇說明了 TryUpdateModel 的簡單的應用,除了可指定更新的欄位之外也可排除更新特定的欄位,而因為可搭配 Metadata 做欄位驗證為資料又做了一層把關,但在 ASP.NET MVC 中我們也很常針對每個的頁面(View)定義專屬的 ViewModel ,而若照個第一篇的寫法會發現欄位無法正確繫結,所以這篇就來教大家如何正確利用 TryUpdateModel 來為我們的 ViewModel 做資料更新 ~

說明

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

public class ProductViewModel
{
public Product ViewProduct { get; set; }
}

透過 ViewModel 所產生的 View 如下:

@model MvcTemplete.Models.ProductViewModel
@{
ViewBag.Title = "Edit";
} @using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Product</legend> @Html.HiddenFor(model => model.ViewProduct.ProductId)
<div class="editor-label">
@Html.LabelFor(model => model.ViewProduct.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ViewProduct.Name)
@Html.ValidationMessageFor(model => model.ViewProduct.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ViewProduct.Ename)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ViewProduct.Ename)
@Html.ValidationMessageFor(model => model.ViewProduct.Ename)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ViewProduct.ModifyUid)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ViewProduct.ModifyUid)
@Html.ValidationMessageFor(model => model.ViewProduct.ModifyUid)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
</span>

接下來我們先看看 Post 回 Controller 時 FormCollection 所接收到集合,如下:

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

由上圖可看到在每個 Key 中包含了 ViewProduct 這個前置詞,因為在 ViewModel 裡我們使用了 Prodcut 這個 Model 且命名為 ViewProduct,如果讀者照著上一篇的 TryUpdateModel 的方法,程式會無法成功繫結。

此時我們可以利用 TryUpdateModel 的另外一個多載來達到資料繫結,程式碼如下:

if(TryUpdateModel(product, "ViewProduct"))
{
db.SaveChanges();
}

而若希望更新特定欄位或排除特定欄位,如下:

if(TryUpdateModel(product, "ViewProduct",new string[] {"Name"},new string[] {"ModifyUid"}))
{
db.SaveChanges();
}

上面的執行結果僅會更新 Name 欄位,而排除更新 ModifyUid 這個欄位。


當然上面的方法還是不夠完美,因為我們並沒有搭配 FormCollection 來做資料繫結並排除特定欄位 ,但因為 FormCollection 內的 Keys 是有加上前置詞,導致無法成功繫結並更新,這部份筆者有寫了個轉換的Code來去掉前置詞,如下:

var Keys = formValue.AllKeys;
List<string> newKeys = new List();
foreach (var item in Keys)
{
newKeys.Add(item.Replace("ViewProduct.", ""));
}
if (TryUpdateModel(product, "ViewProduct", newKeys.ToArray(), new string[] { "ModifyUid" }))
{
db.SaveChanges();
}</string>

OK !大功告成 ~ 不過不知道有沒有其他大大能針對 FormCollection 有前置詞的部份能有其他更好的解法,因為這個解法只是單純去做字串取代而已(逃)。

總結

只能說 TryUpdateModel 在實務上的應用太強大了,如果能善加利用其提供的多載鐵定能應用各種不同的需求,當然還是提醒一下大家使用 TryUpdateModel 時還是要加入「黑名單」或「白名單」,來讓我們的資料更加正確!

上一篇:【Linux】linux ln文件夹的链接(转)


下一篇:Python学习【第四篇】用户输入及判断