We're currently making a small CMS module for our application where existing routes and controllers are highly prioritize, while dynamically created pages through the CMS will only be loaded if the provided URL does not exists in the default route.
I already looked at this one: Dynamic Routes from database for ASP.NET MVC CMS but it prioritizes the dynamically created page before the routes.
This is our default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional }
);
And aside from the default route, we have other routes that are using prefixes like this one:
routes.MapRoute(
name: "Media",
url: "m/{*url}",
defaults: new { controller = "Content", action = "GetContent", contentlibrary = "Media" },
constraints: new { url = @"(.*?)\.(png|jpg|pdf|mpeg|mp3|mp4)" }
);
UPDATE 1: I created an IRouteConstraint for validating if the Controller exists for the default route. Here is my code:
public class ControllerValidatorConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var tempRequestContext = httpContext.Request.RequestContext;
IController controller = null;
try
{
controller = ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, values["controller"].ToString());
}
catch (Exception ex)
{
}
return controller != null;
}
}
then on routing:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional },
constraints: new { url = new ControllerValidatorConstraint() }
);
routes.MapRoute(
name: "Page",
url: "{*url}",
defaults: new { controller = "Content", action = "GetPage" },
constraints: new { url = @"(.*?)(|.cshtml)" },
namespaces: new[] { "AppCore.Controllers" }
);
This already works as what I intend. The only remaining issue is the Match() method. The Match() method is currently creating an instance of the controller, I wrapped it with a Try-Catch block because it throws an error related to the provided path that does not exists as temporary solution but this is still wrong.
I'm almost there, I just have to find a proper way to check if the controller exists. Is reflection a bad choice? Any lighter way to check them? Thanks!