標籤:net oca http請求 工作 attribute c# 路由 選擇 odi
此文摘要小妞之路,記錄一下,方便自己查看學習
Controller Factory控制器工廠:
一般在實際項目中的用法:使用內建的Controller Factory,叫 DefaultControllerFactory。
當 DefaultControllerFactory 類接收到一個 controller 執行個體的請求時,在 DefaultControllerFactory 類內部通過 GetControllerType 方法來獲得 controller 的類型,然後把這個類型傳遞給 GetControllerInstance 方法以獲得 controller 的執行個體。
所以在 GetControllerInstance 方法中就需要有某個東西來建立 controller 執行個體,這個建立的過程就是 controller 被啟用的過程。
預設情況下 MVC 使用 DefaultControllerActivator 類來做 controller 的啟用工作,它實現了 IControllerActivator 介面,該介面定義如下:
public interface IControllerActivator { IController Create(RequestContext requestContext, Type controllerType); }
內建的Action Invoker (ControllerActionInvoker)尋找的是和請求的 action 名稱相同的 action 方法。比如路由系統提供的 action 值是 Index,那麼 ControllerActionInvoker 將尋找一個名為 Index 的方法,如果找到了,它就用這個方法來處理請求。ControllerActionInvoker 允許我們對此行為進行調整,即可以通過使用 ActionName 特性對 action 使用別名,如下對 CustomerController 的 List action 方法使用 ActionName 特性:
public class CustomerController : Controller { ... [ActionName("Enumerate")] public ViewResult List() { return View("Result", new Result { ControllerName = "Customer", ActionName = "List" }); }}
當請求 Enumerate Action 時,將會使用 List 方法來處理請求。下面是請求 /Customer/Enumerate 的結果:
這時候對 /Customer/List 的請求則會無效,報“找不到資源”的錯誤,如下:
使用 Action 方法別名有兩個好處:一是可以使用非法的C#方法名來作為請求的 action 名,如 [ActionName("User-Registration")]。二是,如果你有兩個功能不同的方法,有相同的參數相同的名稱,但針對不同的HTTP請求(一個使用 [HttpGet],另一個使用 [HttpPost]),你可以給這兩個方法不同的方法名,然後使用 [ActionName] 來指定相同的 action 請求名稱。
加一個LocalIndex 方法,並對它應用 “Index”別名,代碼如下:
public class CustomerController : Controller { public ViewResult Index() { return View("Result", new Result { ControllerName = "Customer", ActionName = "Index" }); } [ActionName("Index")] public ViewResult LocalIndex() { return View("Result", new Result { ControllerName = "Customer", ActionName = "LocalIndex" }); }
這時如果請求 /Customer/Index,這兩個 action 方法都會被匹配到而引發歧義問題,程式將會報錯:
我們來考慮這樣一種情況:
所有的 action 選取器都繼承自 ActionMethodSelectorAttribute 類,這個類的定義如下:
using System.Reflection; namespace System.Web.Mvc { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public abstract class ActionMethodSelectorAttribute : Attribute { public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo); } }
同一個URL請求,在本地和遠程請求的是不同的 action (如對於本地則繞過許可權驗證可能需要這麼做)。那麼自訂一個本地的 Action 選取器會是一個不錯的選擇。下面我們來實現這樣一個功能的 Action 選取器:
using System.Reflection;using System.Web.Mvc;namespace MvcApplication2.Infrastructure { public class LocalsAttribute : ActionMethodSelectorAttribute { public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { return controllerContext.HttpContext.Request.IsLocal; } } }
這時候我們再對 LocalIndex 應用我們自訂的 Local 選取器:
...[Locals]//這樣兩個action名字相同時訪問就不會有歧義了[ActionName("Index")]public ViewResult LocalIndex() { return View("Result", new Result { ControllerName = "Customer", ActionName = "Index" });}...
asp.net mvc Controller Factory