I want to keep my URLs as short as possible, so I am testing routes without separators, like this:
routes.MapRoute(
name: "Photo",
url: "x{id}",
defaults: new { controller = "Content", action = "Photo" }
);
For some reason the route above doesn't work, I am getting 404 errors:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.
However when I change the x prefix for a different letter, say g, it's working fine.
There are no conflicting routes. What am I missing here, please?
EDIT:
I am seeing this problem again and I have observed that 404 is probably happening only when the id
contains x, i.e. routes like /xa1B2
or /xZ9y8
work flawlessly, but x12xG
fails. Any ideas, please?
Per MSDN:
You can define more than one placeholder between delimiters, but they must be separated by a constant value. For example, {language}-{country}/{action} is a valid route pattern. However, {language}{country}/{action} is not a valid pattern, because there is no constant or delimiter between the placeholders. Therefore, routing cannot determine where to separate the value for the language placeholder from the value for the country placeholder.
As you already stated, the error happens when your id starts with an x
. This is because there is no way for it to tell the difference between your id value and the constant you have chosen.
Some options that you can use to fix this:
x
.x
and start the second route with another character.The 4th option would look something like this:
// Ids that don't contain x will use this route
routes.MapRoute(
name: "Photo_X",
url: "x{id}",
defaults: new { controller = "Content", action = "Photo" },
constraints: new { id = @"(?i)[^x]" }
);
// Ids that contain x will use this route instead
routes.MapRoute(
name: "Photo_Y",
url: "y{id}",
defaults: new { controller = "Content", action = "Photo" }
);