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

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

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