When building URLs, you have to provide all of the route values that are in the URL pattern. There is one exception - when the last parameter is optional, you don't need to include it.
Therefore, to consistently deal with segments that could be optional in a long URL pattern, you need more than one route. Each route can only have one UrlParameter.Optional
and it must be the right-most segment.
routes.MapRoute("HotToursPage3",
"HotTours/{countryTo}/{resort}/{param1}/{param2}/{param3}/{param4}/{param5}",
new
{
controller = "HotTours",
action = "Index",
param5 = UrlParameter.Optional
}
);
routes.MapRoute("HotToursPage2",
"HotTours/{countryTo}/{resort}/{param1}/{param2}/{param3}",
new
{
controller = "HotTours",
action = "Index",
param3 = UrlParameter.Optional
}
);
routes.MapRoute("HotToursPage1",
"HotTours/{countryTo}/{resort}/{param1}",
new
{
controller = "HotTours",
action = "Index",
param1 = UrlParameter.Optional
}
);
NOTE: I am assuming here that your {countryTo}
and {resort}
parameters are required. It doesn't seem that sensible to make them optional. However, if I am mistaken, you need another route to deal with those 2 segments being optional or alternatively you should provide sensible default values for them. Generally speaking, if there are no sensible defaults for a value it should be required in the URL.
Do note that you still can only make a segment optional if none of the segments to the right of it are provided. Therefore, this combination will work:
var dictionary = new RouteValueDictionary();
dictionary.Add("countryTo", "test1");
dictionary.Add("resort", "test2");
dictionary.Add("param1", "test3");
var url = Url.Action("Index", "HotTours", dictionary);
But this combination will still build a query string:
var dictionary = new RouteValueDictionary();
dictionary.Add("countryTo", "test1");
dictionary.Add("resort", "test2");
dictionary.Add("param1", "test3");
dictionary.Add("param2", "test4");
dictionary.Add("param5", "test5");
var url = Url.Action("Index", "HotTours", dictionary);
If you want all 5 of your params to be optional (and in any order), you should use query strings, rather than putting them into the path.
routes.MapRoute("HotToursPage",
"HotTours/{countryTo}/{resort}",
new
{
controller = "HotTours",
action = "Index"
}
);
An alternative (that I don't recommend) would be to build up a series of routes that have identifier segments, which allows you to place the values in any order. See ASP.Net MVC Handling Segments with Route.