I have MVC3 application that runs under mono on linux.
I have this route:
routes.MapRoute(
"search",
@"search/{term}",
new {
controller = MVC.Mobile.Name,
action = MVC.Mobile.Actions.ActionNames.Search,
term = UrlParameter.Optional
},
new {
term = @"^[0-9]*$"
}
);
which is working fine in windows for both when i show term parameter (e.g. /search/123) or whithout (e.g. /search). Now the problem appears after I deploy it on linux: it return 404 for route without term (e.g. /search) and works fine with term (e.g. /search/123).
I ended up with splitting this route into two:
routes.MapRoute(
"search-empty",
@"search",
new {
controller = MVC.Mobile.Name,
action = MVC.Mobile.Actions.ActionNames.Search
}
);
routes.MapRoute(
"search",
@"search/{term}",
new {
controller = MVC.Mobile.Name,
action = MVC.Mobile.Actions.ActionNames.Search
},
new {
term = @"^[0-9]*$"
}
);
Also I have tried to play with reg exp and define term with default value instead of optional parameter without any success.
Is anybody knows why it is working on windows and isn’t on linux?
The problem arises in the
System.Web.Routing.Route.ProcessConstraint()method.Mono is only evaluating the regex if the value (as string) is not null or empty. If you’re accessing the route without any parameter the value is a
UrlParameterinstance (namelyUrlParameter.Optional) and this as string is null. Thus the expression is never evaluated.To solve this issue you could implement your own Route object and handle things there differently. More on that in my blog post.
And here is the mono implementation which causes the behavior. Look at the
ProcessConstraintInternal()method.MatchConstraintRegex()is only called if the parameter value is not null or empty.