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