Asp.net-Mvc-2
如何在 ASP.NET MVC 中實現動態控制器和動作方法?
在 Asp.net MVC 中,url 結構如下
<http://example.com/> {controller}/{action}/{id}
對於每個“控制器”,比如<http://example.com/blog>,都有一個 BlogController。
但是我的 url 的 {controller} 部分不是預先決定的,而是在執行時動態確定的,我如何創建一個“動態控制器”,將任何東西映射到同一個控制器,然後根據值並確定什麼去做?
{action} 也是一樣,如果我的 url 的 {action} 部分也是動態的,有沒有辦法對這種情況進行程式?
絕對地!
DefaultControllerFactory如果自定義控制器不存在,您將需要覆蓋以查找自定義控制器。然後你需要編寫一個IActionInvoker來處理動態動作名稱。您的控制器工廠將如下所示:
public class DynamicControllerFactory : DefaultControllerFactory { private readonly IServiceLocator _Locator; public DynamicControllerFactory(IServiceLocator locator) { _Locator = locator; } protected override Type GetControllerType(string controllerName) { var controllerType = base.GetControllerType(controllerName); // if a controller wasn't found with a matching name, return our dynamic controller return controllerType ?? typeof (DynamicController); } protected override IController GetControllerInstance(Type controllerType) { var controller = base.GetControllerInstance(controllerType) as Controller; var actionInvoker = _Locator.GetInstance<IActionInvoker>(); if (actionInvoker != null) { controller.ActionInvoker = actionInvoker; } return controller; } }那麼你的動作呼叫者會是這樣的:
public class DynamicActionInvoker : ControllerActionInvoker { private readonly IServiceLocator _Locator; public DynamicActionInvoker(IServiceLocator locator) { _Locator = locator; } protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { // try to match an existing action name first var action = base.FindAction(controllerContext, controllerDescriptor, actionName); if (action != null) { return action; } // @ray247 The remainder of this you'd probably write on your own... var actionFinders = _Locator.GetAllInstances<IFindAction>(); if (actionFinders == null) { return null; } return actionFinders .Select(f => f.FindAction(controllerContext, controllerDescriptor, actionName)) .Where(d => d != null) .FirstOrDefault(); } }您可以在此處看到更多此程式碼。這是我和一位同事編寫完全動態 MVC 管道的舊初稿嘗試。您可以隨意將其用作參考並複制您想要的內容。
編輯
我想我應該包括一些關於該程式碼作用的背景。我們試圖圍繞域模型動態建構 MVC 層。因此,如果您的域包含 Product 類,您可以導航到
products\alls查看所有產品的列表。如果您想添加產品,請導航至product\add. 你可以去product\edit\1編輯一個產品。我們甚至嘗試過允許您編輯實體上的屬性之類的方法。因此product\editprice\1?value=42將產品 #1 的價格屬性設置為 42。(我的路徑可能有點偏離,我不記得確切的語法了。)希望這會有所幫助!