Note that there are some explanatory texts on larger screens.

plurals
  1. POFallback Route in ASP MVC if action doesn't exist
    primarykey
    data
    text
    <p>The default route in MVC <code>{controller}/{action}/{id}</code> is for the most part quite helpful as is being able to set a default if the incoming url doesn't include a parameter but is there also a way to specify a default action for when an action doesn't exist on a controller?</p> <p>What I want to achieve is being able to have controllers with several specific actions and then its own catchall which uses the url to grab content from a basic CMS.</p> <p>For example a products controller would be something like:</p> <pre><code>public class ProductsController: Controller{ public ActionResult ProductInfo(int id){...} public ActionResult AddProduct(){...} public ActionResult ContentFromCms(string url){...} } </code></pre> <p>Where the default route would handle <code>/Products/ProductInfo/54</code> etc but a request url of <code>/Products/Suppliers/Acme</code> would return <code>ContentFromCms("Suppliers/Acme");</code> (sending the url as a parameter would be nicer but not needed and a parameterless method where I get it from Request would be fine).</p> <p>Currently I can think of two possible ways to achieve this, either:</p> <p>Create a new constraint which reflects over a controller to see if it does have an action of a given name and use this in the <code>{controller}/{action}/{id}</code> route thus allowing me to have a more general catchall like <code>{controller}/{*url}</code>.</p> <p>Override <code>HandleUnknownAction</code> on the controller.</p> <p>The first approach seems like it would be quite a roundabout way of checking this while for the second I don't know the internals of MVC and Routing well enough to know how to proceed.</p> <p><strong>Update</strong></p> <p>There's not been any replies but I thought I'd leave my solution incase anyone finds this in future or for people to suggest improvements/better ways</p> <p>For the controllers I that wanted to have their own catchall I gave them an interface </p> <pre><code>interface IHasDefaultController { public string DefaultRouteName { get; } System.Web.Mvc.ActionResult DefaultAction(); } </code></pre> <p>I then derived from the ControllerActionInvoker and overrode FindAction. This calls the base FindAction then, if the base returns null and the controller impliments the interface I call FindAction again with the default actionname. </p> <pre><code>protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { ActionDescriptor foundAction = base.FindAction(controllerContext, controllerDescriptor, actionName); if (foundAction == null &amp;&amp; controllerDescriptor.ControllerType.GetInterface("Kingsweb.Controllers.IWikiController") != null) { foundAction = base.FindAction(controllerContext, controllerDescriptor, "WikiPage"); } return foundAction; } </code></pre> <p>As I also want parameters from the routing I also replace the RouteData at the start of the default Actionresult on the controller</p> <pre><code>ControllerContext.RouteData = Url.RouteCollection[DefaultRouteName].GetRouteData(HttpContext); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload