本系列文章基於ASP.NET MVC Preview5.
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 class AdminController : Controller
{
public ActionResult Setting()
{
throw new NotImplementedException();
}
}
{
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()
{
throw new NotImplementedException();
}
{
throw new NotImplementedException();
}
[ActionName("Setting")]
public ActionResult SaveSetting()
{
throw new NotImplementedException();
}
這兩個Action方法的Action名都爲"Setting",即對於url:Admin/Setting ,能同時匹配到這兩個Action方法。如果一個URL同時匹配到兩個Action方法的話,程序會拋出一個錯誤:
如果我們希望這兩個Action的Action名都爲Setting,Setting()就用於顯示一個表單頁面給用戶,而SaveSetting()就用於保存用戶提交過來的表單數據,我們該怎麼做呢?我們可以利用AcceptVerbsAttribute來設置,這個Attribute用來定義Action方法會匹配指定的HttpMethod。例如下面的代碼:
[AcceptVerbs("GET")]
public ActionResult Setting()
{
throw new NotImplementedException();
}
[ActionName("Setting"), AcceptVerbs("POST")]
public ActionResult SaveSetting()
{
throw new NotImplementedException();
}
public ActionResult Setting()
{
throw new NotImplementedException();
}
[ActionName("Setting"), AcceptVerbs("POST")]
public ActionResult SaveSetting()
{
throw new NotImplementedException();
}
這樣,對於HttpMethod爲"GET"的客戶端請求,就會匹配到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)
{
throw new NotImplementedException();
}
{
throw new NotImplementedException();
}
對於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 = "" } // 設置默認的參數
);
"Default", // Route 的名稱
"{controller}/{action}/{id}", // 帶有參數的URL
new { controller = "Home", action = "Index", id = "" } // 設置默認的參數
);
如果我們將Route修改爲:
routes.MapRoute(
"Default", // Route 的名稱
"{controller}/{action}/{para}", // 帶有參數的URL
new { controller = "Home", action = "Index", para = "" } // 設置默認的參數
);
"Default", // Route 的名稱
"{controller}/{action}/{para}", // 帶有參數的URL
new { controller = "Home", action = "Index", para = "" } // 設置默認的參數
);
則前面的Action方法的參數必須修改爲public ActionResult EditPost(int? para){ },使Action方法的參數和Route中定義的參數名相同,ASP.NET MVC才能自動爲Action方法的參數賦值。
ActionResult
Action方法返回ActionResult類型的結果。ASP.NET MVC爲我們提供了幾種ActionResult的實現,如下:
- ViewResult. 呈現視圖頁給客戶端。由View 方法返回.
- RedirectToRouteResult. 重定向到另外一個Route。由RedirectToAction 和RedirectToRoute 方法返回.
- RedirectResult. 重定向到另外一個URL。由 Redirect 方法返回.
- ContentResult. 返回普通的內容。例如一段字符串。由 Content 方法返回.
- JsonResult. 返回JSON結果。由 Json 方法返回.
- EmptyResult. 如果Action必須返回空值,可以返回這個結果。Controller中沒有實現的方法,可以return new EmptyResult();.
當然我們也可以自定一個我們的ActionResult返回給客戶端,例如一個R***esult。可以參考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)
{
throw new NotImplementedException();
}
public ActionResult Message()
{
throw new NotImplementedException();
}
}
{
public BaseController()
{
}
protected ActionResult ShowMsg(List<string> msgs)
{
throw new NotImplementedException();
}
public ActionResult Message()
{
throw new NotImplementedException();
}
}
然後,其他的Controller都繼承自這個BaseController :
public class AdminController : BaseController
{
[AcceptVerbs("GET")]
public ActionResult Setting()
{
throw new NotImplementedException();
}
[ActionName("Setting"), AcceptVerbs("POST")]
public ActionResult SaveSetting()
{
throw new NotImplementedException();
}
public ActionResult EditPost(int? id)
{
throw new NotImplementedException();
}
}
好,時間不早了,就先到這裏吧。Enjoy!Post by Q.Lee.lulu。{
[AcceptVerbs("GET")]
public ActionResult Setting()
{
throw new NotImplementedException();
}
[ActionName("Setting"), AcceptVerbs("POST")]
public ActionResult SaveSetting()
{
throw new NotImplementedException();
}
public ActionResult EditPost(int? id)
{
throw new NotImplementedException();
}
}
---------------------------------------------------------------------
更多內容,請關注http://blog.51mvc.com/ 和 http://bbs.51mvc.com/
作者:QLeelulu
出處:http://QLeelulu.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利
出處:http://QLeelulu.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利