Controller是MVC中比較重要的一部分。差點兒全部的業務邏輯都是在這裡進行處理的,而且從Model中取出資料。
在ASP.NET MVC Preview5中。将原來的Controller類一分為二,分為了Controller類和ControllerBase類。
Controller類繼承自ControllerBase類,而ControllerBase實作是了IController接口。

ControllerBase實作了IController接口的Execute方法,在Route比對到Controller之後。就會調用Execute方法來進入Controller的處理。
這裡還定義了一個抽象的方法ExecuteCore方法,該方法會在Execute方法的最後被調用。ControllerBase還定義了三個核心的屬性。我們在後面會具體讨論TempData和ViewData。
Controller類除了繼承自ControllerBase類以外。還實作了好幾個Filter接口。Filter我們在後面再具體讨論。
public abstract class Controller
: ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter{ }
Controller類還定義非常多實用的方法,我們建立的Controller都必須繼承自這個Controller類。比如我們建立一個AdminController:
public class AdminController : Controller
{
}
Action方法
以下談一下在Controller中比較重要的Action方法。在ASP.NET MVC中URL都是映射到Controller中的某個Action中,然後由比對的Action來處理我們的業務邏輯并傳回view的。
Controller中的public的方法都被當作是Action方法。Action方法通常傳回一個ActionResult的結果。比如我們為前面的AdminController定義一個Setting的Action方法。用于設定Blog的一些基本參數:
public ActionResult Setting()
{
throw new NotImplementedException();
}
預設情況下,Action方法的方法名就是這個Action的Action名(Action名指的是Route中比對Action方法的URL的那部分。
比如url:Home/Index。當中Index就是Action名)。
這裡為什麼要提到這個Action名呢?應為Action名是能夠定義的。使用ActionNameAttribute來定義。
請看以下的示範樣例:
public ActionResult Setting()
throw new NotImplementedException();
[ActionName("Setting")]
public ActionResult SaveSetting()
這兩個Action方法的Action名都為"Setting",即對于url:Admin/Setting ,能同一時候比對到這兩個Action方法。假設一個URL同一時候比對到兩個Action方法的話。程式會抛出一個錯誤:
假設我們希望這兩個Action的Action名都為Setting。Setting()就用于顯示一個表單頁面給使用者,而SaveSetting()就用于儲存使用者送出過來的表單資料,我們該怎麼做呢?我們能夠利用AcceptVerbsAttribute來設定,這個Attribute用來定義Action方法會比對指定的HttpMethod。比如以下的代碼:
[AcceptVerbs("GET")]
[ActionName("Setting"), AcceptVerbs("POST")]
這樣,對于HttpMethod為"GET"的client請求,就會比對到Setting()來顯示一個表單給使用者。假設使用者POST回來的表單資料,則會比對到SaveSetting()上面去。我們就能夠處理使用者POST過來的資料并儲存到資料庫。
在這裡AcceptVerbsAttribute是繼承自ActionSelectionAttribute的。我們也能夠繼承自ActionSelectionAttribute來自己定義自己想要實作的功能。這個我們後面會具體解說。假設你比較心急,能夠看下Asp.net Mvc Preview 5 體驗--實作ActionSelectionAttribute來推斷是否為AJAX請求而選擇不同的Action這篇文章。
假設你想将一個public的方法設定為不是Action方法,那麼你就要為該public的方法加入NonAction的Attribute:
Action方法的參數
比如我們要在AdminController中定義一個編輯日志的Action方法:
public ActionResult EditPost(int? id)
對于URL:Admin/EditPost/2 。上面的參數會自己主動被指派為2。ASP.NET MVC在比對Route的時候會依據Route的設定自己主動為Action方法的參數指派。
所曾經面的id參數會被自己主動指派為2的前提是,在Route配置的時候,必須指定了id參數。比如:
routes.MapRoute(
"Default",
// Route 的名稱
"{controller}/{action}/{id}", // 帶有參數的URL
new { controller= "Home", action
= "Index", id
= "" }
// 設定預設的參數
);
假設我們将Route改動為:
"{controller}/{action}/{para}", // 帶有參數的URL
= "Index",
para = "" }
則前面的Action方法的參數必須改動為public ActionResult EditPost(int? para){ },使Action方法的參數和Route中定義的參數名同樣,ASP.NET MVC才幹自己主動為Action方法的參數指派。
ActionResult
Action方法傳回ActionResult類型的結果。ASP.NET MVC為我們提供了幾種ActionResult的實作。例如以下:
ViewResult. 呈現視圖頁給client。
由View 方法傳回.
RedirectToRouteResult. 重定向到另外一個Route。由RedirectToAction 和RedirectToRoute 方法傳回.
RedirectResult. 重定向到另外一個URL。
由Redirect 方法傳回.
ContentResult. 傳回普通的内容。比如一段字元串。
由Content 方法傳回.
JsonResult. 傳回JSON結果。由Json 方法傳回.
EmptyResult. 假設Action必須傳回空值,能夠傳回這個結果。Controller中沒有實作的方法。能夠return new EmptyResult();.
當然我們也能夠自定一個我們的ActionResult傳回給client,比如一個RssResult。
能夠參考Asp.Net MVC實踐 - 自己定義ActionResult實作Rss輸出 (基于ASP.NET MVC Preview 3)這篇文章。
通常情況下。我們的Controller可能有一些同樣的情況,比如我們在各個Controller中都有可能會在出錯或者什麼時候想要顯示一條提示資訊給使用者,或者有一些共同的資料要呈現的。這時候,我們最好就定義一個我們自己的Controller的基類:
public class BaseController : Controller
public BaseController()
protected ActionResult ShowMsg(List<string>
msgs)
public ActionResult Message()
然後。其它的Controller都繼承自這個BaseController :
public class AdminController : BaseController
[AcceptVerbs("GET")]
[ActionName("Setting"), AcceptVerbs("POST")]
public ActionResult SaveSetting()
public ActionResult EditPost(int? id)