ASP.NET MVC 入門4、Controller與Action

本系列文章基於ASP.NET MVC Preview5.
Controller是MVC中比較重要的一部分。幾乎所有的業務邏輯都是在這裏進行處理的,並且從Model中取出數據。在ASP.NET MVC Preview5中,將原來的Controller類一分爲二,分爲了Controller類和ControllerBase類。Controller類繼承自ControllerBase類,而ControllerBase實現是了IController接口。
p_w_picpath
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();
    }
}
複製代碼
 
默認情況下,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();
}
複製代碼
 
這兩個Action方法的Action名都爲"Setting",即對於url:Admin/Setting ,能同時匹配到這兩個Action方法。如果一個URL同時匹配到兩個Action方法的話,程序會拋出一個錯誤:
p_w_picpath
如果我們希望這兩個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();
}
複製代碼
 
這樣,對於HttpMethod爲"GET"的客戶端請求,就會匹配到Setting()來顯示一個表單給用戶,如果用戶POST回來的表單數據,則會匹配到SaveSetting()上面去,我們就可以處理用戶POST過來的數據並保存到數據庫。
在這裏AcceptVerbsAttribute是繼承自ActionSelectionAttribute的,我們也可以繼承自ActionSelectionAttribute來自定義自己想要實現的功能。這個我們後面會詳細講解。如果你比較心急,可以看下Asp.net Mvc Preview 5 體驗--實現ActionSelectionAttribute來判斷是否爲AJAX請求而選擇不同的Action這篇文章。
如果你想將一個public的方法設置爲不是Action方法,那麼你就要爲該public的方法添加NonAction的Attribute:
p_w_picpath
Action方法的參數
例如我們要在AdminController中定義一個編輯日誌的Action方法:
public ActionResult EditPost(int? id)
{
    
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 = "" }  // 設置默認的參數
);
 
如果我們將Route修改爲:
routes.MapRoute(
    
"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();
    }
}
複製代碼
 
然後,其他的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
---------------------------------------------------------------------
更多內容,請關注http://blog.51mvc.com/ 和 http://bbs.51mvc.com/
作者:QLeelulu Follow 
出處:http://QLeelulu.cnblogs.com/ 
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章