Sam's answer is good but I would do it the other way around. If your parameter {sub} for "someValue" is dynamic (stored in database) I would create a constraint that excludes your existing controllers. So If you call
domain.com/home
or domain.com/contact
it would reach these controllers otherwise route through categories. For example:
public class NotEqual : IRouteConstraint
{
private string[] _match = null;
public NotEqual(string[] match)
{
_match = match;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
foreach(var controllername in _match)
{
if (String.Compare(values[parameterName].ToString(), controllername, true) == 0)
return false;
}
return true;
}
}
Modified version of: http://stephenwalther.com/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints
and your route would be:
routes.MapRoute(
name: "categories",
url: "{sub}",
defaults: new { controller = "cat", action = "Index" }
, constraints: new { sub = new NotEqual(new string[] { "Contact", "Home" }) }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
This way whatever you put that is different to domain.com/contact
or domain.com/home
will get re-routed to your cat controller
@Url.Action("Index","Contact")
Should produce:
/Contact