In Asp.net MVC the url structure goes like
http://example.com/{controller}/{action}/{id}
For each "controller", say http://example.com/blog, there is a BlogController.
But my {controller} portion of the url is not decided pre-hand, but it is dynamically determined at run time, how do I create a "dynamic controller" that maps anything to the same controller which then based on the value and determines what to do?
Same thing with {action}, if the {action} portion of my url is also dynamic, is there a way to program this scenario?
ASP.NET MVC Action Methods are responsible to execute requests and generate responses to it. By default, it generates a response in the form of ActionResult. Actions typically have a one-to-one mapping with user interactions.
An action (or action method ) is a method on a controller that handles incoming requests. Controllers provide a logical means of grouping similar actions together, allowing common sets of rules (e.g. routing, caching, authorization) to be applied collectively. Incoming requests are mapped to actions through routing.
Figure 2: Types of Action Result There are two methods in Action Result. One is ActionResult() and another one is ExecuteResult().
- Action method cannot be a static method. ActionResult is a base class of all the result type which returns from Action method.
Absolutely! You'll need to override the DefaultControllerFactory to find a custom controller if one doesn't exist. Then you'll need to write an IActionInvoker to handle dynamic action names.
Your controller factory will look something like:
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;     } }   Then your action invoker would be like:
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();     } }   You can see a lot more of this code here. It's an old first draft attempt by myself and a coworker at writing a fully dynamic MVC pipeline. You're free to use it as a reference and copy what you want.
Edit
I figured I should include some background about what that code does. We were trying to dynamically build the MVC layer around a domain model. So if your domain contained a Product class, you could navigate to products\alls to see a list of all products. If you wanted to add a product, you'd navigate to product\add. You could go to product\edit\1 to edit a product. We even tried things like allowing you to edit properties on an entity. So product\editprice\1?value=42 would set the price property of product #1 to 42. (My paths might be a little off, I can't recall the exact syntax anymore.) Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With