ASP.NET MVC學習筆記-----ActionInvoker

仍是這張圖:框架

當ControllerFactory生成Controller實例後,這時就須要使用ActionInvoker來選擇調用一個合適的Action執行。ASP.NET MVC提供的基類Controller已經實現了ActionInvoker的功能。可是咱們能夠實現自定義的ActionInvoker來替代框架中提供的ActionInvoker。ide

首先一個ActionInvoker須要實現IActionInvoker接口:函數

public interface IActionInvoker
{
    bool InvokeAction(ControllerContext controllerContext, string actionName) ;     
}

InvokeAction參數有兩個,其中controllerContext包含當前Controller信息和請求信息,而actionName則是用調用的action名。當函數找到一個合適的Action併成功調用時返回true,不然返回false。post

那咱們要怎樣才能使用自定義的ActionInvoker呢,Controller類給咱們提供了ActionInvoker屬性,因此咱們能夠經過設置該屬性讓MVC使用咱們的ActionInvoker:this

    public class HomeController : Controller
    {
        public HomeController() 
        {
            this.ActionInvoker = new MyActionInvoker();
        }

        //....其餘代碼.....
    }

MVC中內置的ActionInvokerspa

 上面也說了,基類Controller實現了ActionInvoker的功能,它使用的就是MVC內置的ActionInvoker-----ControllerActionInvoker。code

 一個方法要被ControllerActionInvoker看成一個Action須要知足如下條件:orm

  1.該方法的做用域必須爲publicblog

  2.該方法不能是靜態方法接口

  3.該方法不能是Controller基類的方法

  4.該方法不能是構造函數

另外:若是方法是一個泛型方法,比且符合以上條件,則會在嘗試調用的時候拋出一個異常

默認的,ControllerActionInvoker會將與actionName相同的方法名的方法做爲Action,並調用。可是若是一個Controller中有多個同名的重載的方法時怎麼辦呢,咱們可使用ActionNameAttribute特性來設置Action別名:

    public class HomeController : Controller
    {      
        [ActionName("Enumerate")]
        public ActionResult List() 
        {
            return View();
        }
    }

 這樣當咱們請求/home/enumerate 時,調用的Action就是List,但當咱們請求/home/list時,List將不會被調用,在這個例子中將返回404頁面。

 除了別名,ControllerActionInvoker還使用了action method selection(選擇偏好)機制來處理如何選擇多個同名的方法,來看下面的代碼:

        [HttpGet]
        public ViewResult MyAction(int? id)
        {
            return View(id);
        }

        [HttpPost]
        public ViewResult MyAction(Product product)
        {
            return View(product);
        }

 這個你們應該都很清楚了,當get請求時調用的是MyAction(int? id),而post請求時調用的是MyAction(Product product)。這就是action method selection。

 咱們能夠建立自定義的Action Method選擇器,來設定ControllerActionInvoker的選擇偏好。

    public class ActionMethodSelectorAttribute : Attribute
    {
        public bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            return controllerContext.HttpContext.Request.IsLocal;
        }
    }

 選擇器須要有IsValidForRequest方法,當方法返回true時,表示符合偏好,會優先調用該方法。

 ControllerActionInvoker未找到合適Action時的處理:

在這種狀況下將會調用Controller的HandleUnknowAction方法,這個方法將會顯示404頁面,可是咱們能夠重寫該方法以改變默認行爲:

        protected override void HandleUnknownAction(string actionName)
        {
            Response.Write(string.Format("未發現你要找的Action: {0}", actionName));
        }
相關文章
相關標籤/搜索