Reputation: 351
I have this default mapRoute:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
and some other mapRoutes for some other sontrollers before default,
now, I want a mapRoute for special controller to show the url like : myDomain.com/someValue, but when I use this:
routes.MapRoute(
name: "categories",
url: "{sub}",
defaults: new { controller = "cat", action = "Index" }
);
all of my url.Actions which have "Index" as action like @Url.Action("index","login") not work, I have also used :
sub=UrlParameter.Optional
and
sub=""
, but they did not work, what should I do ?
Upvotes: 1
Views: 1257
Reputation: 14741
Your categories
route catches all urls because it is match with the role. You need to write a custom constraint class to filter out unmatched sub
s form your database for example.
public class MyCatConstraint : IRouteConstraint
{
// suppose this is your cats list. In the real world a DB provider
private string[] _myCats = new[] { "cat1", "cat2", "cat3" };
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
// return true if you found a match on your cat's list otherwise false
// in the real world you could query from DB to match cats instead of searching from the array.
if(values.ContainsKey(parameterName))
{
return _myCats.Any(c => c == values[parameterName].ToString());
}
return false;
}
}
and then add this constraint to your route.
routes.MapRoute(
name: "categories",
url: "{sub}",
defaults: new { controller = "cat", action = "Index" }
,constraints: new { sub = new MyCatConstraint() }
);
Upvotes: 0
Reputation: 4273
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
Upvotes: 0