The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

ASP.NET MVC 開發心得分享 (4):微調 Model Binder 屬性

我在對公司內部進行 ASP.NET MVC 教育訓練時有寫到一個「新增新聞」這個 Action 方法,由於傳入的資料已經透過 DefaultModelBinder 將 Request.Form 的資料轉成 LINQ to SQL 的 News 型別了,這個 Action 的程式碼如下:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "ID")] News n)
{
    if (ModelState.IsValid)
    {
        db.AddToNews(n);
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    else
    {
        return View();
    }
}

你可以看到我們在傳入 Create 這個 Action 時,只有 News 一個參數,由於在新增 News 時我們會在 LINQ to SQL 的 partial class 中驗證每一個欄位,當然也包括 ID 欄位 ( 因為 Primary Key 不能為 Null ),所以如果不加上 [Bind(Exclude = "ID")] 的話,在執行時 ModelState.IsValid 就會永遠都是 False 而導致無法新增成功。

但是當 Action 一多,麻煩事也就來了,難倒每個 Action 都要加上這個 Attribute 嗎?其實是不用的!

你只要在 LINQ to SQL 的 partial class 中集中宣告一次就可以了:

namespace MvcApplication1.Models
{
    [System.Web.Mvc.Bind(Exclude = "ID")]
    public partial class News
    {
        ...
        ...
        ...
    }
}

如此一來 Action 的程式碼又可以更少了。

---

在 ASP.NET MVC 的世界裡,最最最重要的觀念就是 separation of concerns (SoC),無論是 Model ( LINQ to SQL, Entity Framework, ... ), View ( HTML, Ajax, jQuery, ... ), Controller ( Action, Action Filter ) 或是 Model Binder, Helper method, Repository Pattern, Inversion of control (IoC), ... 以及各種各式這樣的 Design Pattern,最主要的目的就是為了讓開發程式時可以將複雜度降低,減少錯誤發生率,以及讓不同的層級(Layer)或不同的角度(Point of View)的程式得以專注在該角度解決問題,進而提升分工效率,而且不只是「程式、物件」的分工,甚至於「人」的分工也可以達到,不同人負責不同的領域,在 ASP.NET MVC 的世界裡是非常容易達成的,這也是我熱愛 ASP.NET MVC 的原因之一。