tutorial net mvc filtro entre diferencias busqueda asp asp.net-mvc-2 asp.net-mvc-routing asp.net-mvc-controller

asp.net mvc 2 - filtro - ¿Cómo lograr un controlador dinámico y un método de acción en ASP.NET MVC?



web forms c# (3)

Después de un poco más de reflexión, puede haber una forma un poco más sencilla de manejar los nombres de acciones dinámicas que mi otra respuesta. Aún deberá anular la fábrica de controladores predeterminada. Creo que podrías definir tu ruta como:

routes.MapRoute("Dynamic", "{controller}/{command}/{id}", new { action = "ProcessCommand" });

Entonces en tu controlador predeterminado / dinámico tendrías

public ActionResult ProcessCommand(string command, int id) { switch(command) { // whatever. } }

En Asp.net MVC la estructura url es como

http://example.com/ {controlador} / {acción} / {id}

Para cada "controlador", digamos http://example.com/blog , hay un BlogController.

Pero mi parte de {url} de la url no se decide de antemano, pero se determina dinámicamente en el tiempo de ejecución, ¿cómo puedo crear un "controlador dinámico" que asigne algo al mismo controlador que luego se basa en el valor y determina qué? ¿que hacer?

Lo mismo con {acción}, si la parte de {acción} de mi url también es dinámica, ¿hay alguna manera de programar este escenario?


¡Absolutamente! Tendrá que anular el DefaultControllerFactory para encontrar un controlador personalizado si no existe uno. Entonces deberás escribir un IActionInvoker para manejar nombres de acción dinámicos.

Su fábrica de controladores se verá algo como:

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; } }

Entonces tu invocador de acción sería como:

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(); } }

Puedes ver mucho más de este código here . Es un antiguo primer intento de borrador por mi parte y un compañero de trabajo para escribir un pipeline MVC completamente dinámico. Eres libre de usarlo como referencia y copiar lo que quieras.

Editar

Pensé que debería incluir algunos antecedentes sobre lo que hace ese código. Estábamos tratando de construir dinámicamente la capa MVC alrededor de un modelo de dominio. Por lo tanto, si su dominio contiene una clase de Producto, puede navegar a products/alls para ver una lista de todos los productos. Si quisiera agregar un producto, navegaría a product/add . Puede ir al product/edit/1 para editar un producto. Incluso intentamos cosas como permitirte editar propiedades en una entidad. Entonces, product/editprice/1?value=42 establecería la propiedad de precio del producto # 1 a 42. (Mis rutas pueden ser un poco desagradables, ya no puedo recordar la sintaxis exacta). ¡Espero que esto ayude!


IControllerFactory escribir su propia IControllerFactory (o tal vez derivar de DefaultControllerFactory ) y luego registrarla con ControllerBuilder .