2

I'm creating a cut down version of a CMS using MVC 5 and I'm trying to get through the routing side of things.

I need to handle pages with urls such as /how-it-works/ and /about-us/ etc and therefore content is keyed on these paths.

In my RouteConfig file I'm using a 'catch all' route as follows::

routes.MapRoute("Static page", "{*path}", new { controller = "Content", action = "StaticPage" });

This successfully hits the controller action I'm looking, however it therefore means that requests for controller actions that actually do exist (for example /navigation/main also get sent down this route).

I know that I can have a route that matches /navigation/main however I'd rather configure MVC to do this as default, like it does when I don't add the rule I have above, any ideas?

andrewm
  • 2,552
  • 5
  • 33
  • 63
  • Add a route constrain to your "catch all" route for {*path}. And in route.config place the "Default" MVC route at bottom. – tmg Apr 01 '15 at 17:31
  • could you possibly explain further? – andrewm Apr 02 '15 at 07:41
  • Possible duplicate of [Dynamic Routes from database for ASP.NET MVC CMS](http://stackoverflow.com/questions/16026441/dynamic-routes-from-database-for-asp-net-mvc-cms) – hacker Sep 21 '16 at 19:44

1 Answers1

2

Add your "catch all" route on top of "default" route and add a route constrain to path like this:

public class RouteConfig
{
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


            routes.MapRoute(
                "Static page", 
                 "{*path}", 
                 new { controller = "Content", action = "StaticPage" }
                 new { path = new PathConstraint() });

            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });
       }
}

PathConstraint should derive from from IRouteConstraint interface and can be something like this:

public class PathConstraint: IRouteConstraint
{        

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            if (values[parameterName] != null)
            {
                var permalink = values[parameterName].ToString();
                //gather all possible paths from database 
                //and check if permalink is any of them 
                //return true or false
                return database.GetPAths().Any(p => p == permalink);
            }
            return false;
        }
    }

So if "path" is not one of your pages paths, PathConstrain will not be satisified and "Static page" route will be skiped and pass to next route.

tmg
  • 19,895
  • 5
  • 72
  • 76