ASP.NET MVC 入门4、Controller与Action
本系列文章基于ASP.NET MVC Preview5.
Controller是MVC中比較重要的一部分。幾乎所有的業(yè)務(wù)邏輯都是在這里進行處理的,并且從Model中取出數(shù)據(jù)。在ASP.NET MVC Preview5中,將原來的Controller類一分為二,分為了Controller類和ControllerBase類。Controller類繼承自ControllerBase類,而ControllerBase實現(xiàn)是了IController接口。
ControllerBase實現(xiàn)了IController接口的Execute方法,在Route匹配到Controller之后,就會調(diào)用Execute方法來進入Controller的處理。這里還定義了一個抽象的方法ExecuteCore方法,該方法會在Execute方法的最后被調(diào)用。ControllerBase還定義了三個核心的屬性。我們在后面會詳細(xì)討論TempData和ViewData。
Controller類除了繼承自ControllerBase類以外,還實現(xiàn)了好幾個Filter接口,Filter我們在后面再詳細(xì)討論。
public?abstract?class?Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter{ }
Controller類還定義很多有用的方法,我們新建的Controller都必須繼承自這個Controller類。例如我們新建一個AdminController:
{
}
?
Action方法
下面談一下在Controller中比較重要的Action方法。在ASP.NET MVC中URL都是映射到Controller中的某個Action中,然后由匹配的Action來處理我們的業(yè)務(wù)邏輯并返回view的。
Controller中的public的方法都被當(dāng)作是Action方法。Action方法通常返回一個ActionResult的結(jié)果。例如我們?yōu)榍懊娴腁dminController定義一個Setting的Action方法,用于設(shè)置Blog的一些基本參數(shù):
public?class?AdminController : Controller{
????public?ActionResult Setting()
??? {
????????throw?new?NotImplementedException();
??? }
}
?
默認(rèn)情況下,Action方法的方法名就是這個Action的Action名(Action名指的是Route中匹配Action方法的URL的那部分。例如url:Home/Index,其中Index就是Action名)。這里為什么要提到這個Action名呢?應(yīng)為Action名是可以定義的,使用ActionNameAttribute來定義。請看下面的示例:
public?ActionResult Setting(){
????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()就用于保存用戶提交過來的表單數(shù)據(jù),我們該怎么做呢?我們可以利用AcceptVerbsAttribute來設(shè)置,這個Attribute用來定義Action方法會匹配指定的HttpMethod。例如下面的代碼:
[AcceptVerbs("GET")]public?ActionResult Setting()
{
????throw?new?NotImplementedException();
}?
[ActionName("Setting"), AcceptVerbs("POST")]
public?ActionResult SaveSetting()
{
????throw?new?NotImplementedException();
}
?
這樣,對于HttpMethod為"GET"的客戶端請求,就會匹配到Setting()來顯示一個表單給用戶,如果用戶POST回來的表單數(shù)據(jù),則會匹配到SaveSetting()上面去,我們就可以處理用戶POST過來的數(shù)據(jù)并保存到數(shù)據(jù)庫。
在這里AcceptVerbsAttribute是繼承自ActionSelectionAttribute的,我們也可以繼承自ActionSelectionAttribute來自定義自己想要實現(xiàn)的功能。這個我們后面會詳細(xì)講解。如果你比較心急,可以看下Asp.net Mvc Preview 5 體驗--實現(xiàn)ActionSelectionAttribute來判斷是否為AJAX請求而選擇不同的Action這篇文章。
如果你想將一個public的方法設(shè)置為不是Action方法,那么你就要為該public的方法添加NonAction的Attribute:
Action方法的參數(shù)
例如我們要在AdminController中定義一個編輯日志的Action方法:
public?ActionResult EditPost(int??id){
????throw?new?NotImplementedException();
}
?
對于URL:Admin/EditPost/2 ,上面的參數(shù)會自動被賦值為2。ASP.NET MVC在匹配Route的時候會根據(jù)Route的設(shè)置自動為Action方法的參數(shù)賦值。所以前面的id參數(shù)會被自動賦值為2的前提是,在Route配置的時候,必須指定了id參數(shù),例如:
routes.MapRoute(????"Default",??????????????????????????????????????????????//?Route 的名稱
????"{controller}/{action}/{id}",???????????????????????????//?帶有參數(shù)的URL
????new?{ controller?=?"Home", action?=?"Index", id?=?""?}??//?設(shè)置默認(rèn)的參數(shù)
);
?
如果我們將Route修改為:
routes.MapRoute(????"Default",??????????????????????????????????????????????//?Route 的名稱
????"{controller}/{action}/{para}",???????????????????????????//?帶有參數(shù)的URL
????new?{ controller?=?"Home", action?=?"Index",?para?=?""?}??//?設(shè)置默認(rèn)的參數(shù)
);
?
則前面的Action方法的參數(shù)必須修改為public ActionResult EditPost(int??para){ },使Action方法的參數(shù)和Route中定義的參數(shù)名相同,ASP.NET MVC才能自動為Action方法的參數(shù)賦值。
ActionResult
Action方法返回ActionResult類型的結(jié)果。ASP.NET MVC為我們提供了幾種ActionResult的實現(xiàn),如下:
-
ViewResult. 呈現(xiàn)視圖頁給客戶端。由View?方法返回.
-
RedirectToRouteResult. 重定向到另外一個Route。由RedirectToAction?和RedirectToRoute?方法返回.
-
RedirectResult. 重定向到另外一個URL。由?Redirect?方法返回.
-
ContentResult. 返回普通的內(nèi)容。例如一段字符串。由?Content?方法返回.
-
JsonResult. 返回JSON結(jié)果。由?Json?方法返回.
-
EmptyResult. 如果Action必須返回空值,可以返回這個結(jié)果。Controller中沒有實現(xiàn)的方法,可以return new EmptyResult();.
當(dāng)然我們也可以自定一個我們的ActionResult返回給客戶端,例如一個RssResult。可以參考Asp.Net MVC實踐 - 自定義ActionResult實現(xiàn)Rss輸出 (基于ASP.NET MVC Preview 3)這篇文章。
通常情況下,我們的Controller可能有一些相同的情況,例如我們在各個Controller中都有可能會在出錯或者什么時候想要顯示一條提示信息給用戶,或者有一些共同的數(shù)據(jù)要呈現(xiàn)的。這時候,我們最好就定義一個我們自己的Controller的基類:
public?class?BaseController : Controller{
????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。
總結(jié)
以上是生活随笔為你收集整理的ASP.NET MVC 入门4、Controller与Action的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一节:复习委托,并且通过委托的异步调用
- 下一篇: ASP.NET Core管道深度剖析(3