I have this route:
routes.MapRoute(
"News",
"News/{id}-{alias}",
new { controller = "News", action = "Show" },
new
{
id = @"^[0-9]+$"
},
namespaces: new[] { "Site.Controllers" }
);
This route working for url's like this:
http://localhost:54010/News/6-news
But not working for url's like this:
http://localhost:54010/News/6-nice-news
How use dashes in my route value "alias"?
EDITED
Route like this:
"News/{id}_{alias}"
works for both url's:
http://localhost:54010/News/6_news
http://localhost:54010/News/6_nice-news
The problem is with your pattern: News/{id}-{alias}
because the Routeing is parsing the patterns greedily.
So the url http://localhost:54010/News/6-news
generates the following tokens:
id = 6, alias = news
But the http://localhost:54010/News/6-nice-news
generates the following tokens:
id = 6-nice, alias = news
And the id = 6-nice
token will fail your routing contraint @"^[0-9]+$".
so you will get 404.
There is now way to configure this behavior of MVC so you have the following options:
- Use something else than dashes. As you noted combining dashes and hyphens works.
- Take flem approach and parse inside the id and alias inside your controller action
- You can create a custom
Route
which will take of the re-parsing. E.g transforming id = 6-nice, alias = news
to id = 6, alias = news-nice
I will show you a raw (without any error handling or good coding practices!) implementation of the option 3 to get you started.
So you need to inherit from Route
:
public class MyRoute : Route
{
public MyRoute(string url,
RouteValueDictionary defaults,
RouteValueDictionary constraints,
RouteValueDictionary dataTokens)
: base(url, defaults, constraints, dataTokens, new MvcRouteHandler())
{
}
protected override bool ProcessConstraint(HttpContextBase httpContext,
object constraint, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
var parts = ((string) values["id"]).Split('-');
if (parts.Length > 1)
{
values["id"] = parts[0];
values["alias"] = // build up the alias part
string.Join("-", parts.Skip(1)) + "-" + values["alias"];
}
var processConstraint = base.ProcessConstraint(httpContext, constraint,
parameterName, values, routeDirection);
return processConstraint;
}
}
Then you just need to register your route:
routes.Add("News",
new MyRoute("News/{id}-{alias}",
new RouteValueDictionary(new {controller = "News", action = "Show"}),
new RouteValueDictionary(new
{
id = @"^[0-9]+$"
}),
new RouteValueDictionary()));