我在對公司內部進行 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 的原因之一。