For SEO and SEM reasons I have been asked to implement the following URL in our MVC ASP.NET application:
/colour/{colour1}/[{colour2}]/[{colour3}]/[{colour4}]/fill
In all cases the URL needs to start with /colour and end with /fill. There will be at leastcolour1 and optionally three additional colours ({colour2..4}) so all of the following are valid:
/colour/red/fill
/colour/red/blue/fill
/colour/red/blue/green/fill
/colour/red/blue/green/yellow/fill
/colour/yellow/blue/green/red/fill
The following does NOT work:
aRoutes.MapRoute("Blah", "colour/{colour1}/{colour2}/{colour3}/{colour4}/fills", new
{
controller = "MyController",
action = "MyAction",
colour2 = UrlParameter.Optional,
colour3 = UrlParameter.Optional,
colour4 = UrlParameter.Optional
});
[HttpGet]
public virtual ActionResult MyAction(string colour1, string colour2 = "", string colour3 = "", string colour4 = "")
{
return null;
}
and neither does:
aRoutes.MapRoute("Blah", "colour/{*colour}/fills", new
{
controller = "MyController",
action = "MyAction2",
});
as the trailing /fills causes an issue.
So my questions are:
- Can this all be done with a single route definition in route config? What is the minimal amount of route configuration I need to have to achieve this?
- Can I have a single action method in my controller to handle all of these? Or do I need to declare a separate method based on each of the number of parameters?
2
Answers
The solution I was able to implement requires additional routes to be declared that are all directed to the same method. Be sure to declare them in descending order in terms of the number of parameters (so all 4 first and the single one last):
and the controller method looks like:
Ultimately not a great solution because if we wanted to add colour5 then we would need to modify the route table and the action method. But that is how the cookie crumbles in this case.
Catch-All needs to be the last parameter in the list.
Visual Studio will throw the following error if you have the /fill after the catch-all:
Easiest solution would be to move the /fill to before the catch-all if it is static. If /fill is the action for the colours, perhaps use /colourAction/{colourAction} to pull the action to your function in the Controller?
https://msdn.microsoft.com/en-us/library/cc668201.aspx#Anchor_5