Closed Bitsonthefloor closed 11 years ago
Default values will only work when the url has no static section following the param (following the rules for optionals, as the default is only used if the param has no value). Constraints work anywhere.
"{p1=default}/static" // this won't work
"{p1=default1}/{p2=default2}" // this will work if the params are not given, yielding "default1/default2"
It is not that the defautls are not working, its that the code is not parsing the defaults out of the url, DefaultValues are only parsed from the routes specified RouteUrl, whereas Constraints are parsed from the url built from the BuildTokenizedUrl. This is mostly useful for url building (i.e. enforcing default values in a RouteUrl method).
An example: Lets say I have [RouteArea("Api", AreaUrl="Api/{version:decimal=1.0}")]
The expected output when Url.RouteUrl([some action]) would be /Api/1.0/[some action], however because the DefaultValues of the route does not have the 1.0, unless the 1.0 is specified as a value in a dictionary, the result is a null since no route matched.
Ah, I see now. Thanks for reporting.
Hmm, actually what you showed me will suffer from the problems I mentioned above. Defaults, to my knowledge, don't work when they are between static sections. I'll mess around a bit to try and repro.
Here is an example to try:
[RoutePrefix("Controller/{version:decimal=1.0}")] public class ControllerTestController : Controller {
[GET("{param:long=1}/Action")] public ActionResult TAction() { return View(); }
}
If you look at the route created it will have an entry in Constraints but no entry in DefaultValues for version, but param will have an entry in both. in a view if you do the following:
@Url.Action(new { controller = "ControllerTest", Action = "TAction" }) @Url.Action(new { controller = "ControllerTest", Action = "TAction", version = "1.0" })
The first Url.Action will not match, but the second will, though both should match and return Controller/1.0/1/Action
what your thinking of is when the routing engine is parsing a url and in that situation the {version} would not match when missing because the url parser would expect a value between the two statics, it can only handle missing values on the end.
Fix available in 3.5.3.
If you use default values and constraints in either AreaUrl or RoutePrefix, the constraints will be passed into the resulting route but any default values will not. It seems to be because CreateRouteConstraints in RouteBuilder uses BuildTokenizedUrl where CreateRouteDefaults only uses routeSpec.RouteUrl