Reputation: 375
My MVC web application generates an activation link that can include any character (%,+,/,etc.). I URL encode the string and generate link:
new UrlHelper(HttpContext.Current.Request.RequestContext)
.RouteUrl("AccountActivation",
new { id = HttpContext.Current.Server.UrlEncode(activationString) };
then add the domain and it looks like:
http://localhost/AccountActivation/asdlkj223%25asd%2Basw3fgasdme
The URL is then passed to the user.
The route in this case is:
routes.MapRoute(
"ActivateAccount",
"AccountActivation/{id}",
new { controller = "Account", action = "Activate", id = ""});
It seem fine to me, but the ASP.NET development server and IIS give me HTTP Error 400 - Bad request. Which means there's a problem with the URL that I can't see.
When get rid of the {id} in the route description (I also tried {*id} with no success):
routes.MapRoute(
"ActivateAccount",
"AccountActivation",
new { controller = "Account", action = "Activate"});
the URLs look like:
http://AccountActivation?id=asdlkj223%25asd%2Basw3fgasdme
and they work just fine...
I though those 2 approaches do exactly the same thing. What is the difference between them? Is it the MVC engine that performs something more for me or I miss something with the URL encoding.
Upvotes: 3
Views: 6365
Reputation: 42343
Try UrlPathEncode
instead of UrlEncode
- some characters are illegal in the path that are legal in a query string.
That said - I believe the analysis of whether a character is 'bad' is performed after path-decoding occurs; and is done by IIS. It will reject some characters because of the possibility that the URL maps to the physical file-system and therefore could allow a user access to things they really shouldn't have access to. Equally it's done to prevent requests from sending data that really shouldn't be sent.
Generally if there's operationally no benefit from having a parameter mapped as a route parameter, then don't try too hard to map it - especially in this case where the string could be anything.
By the way - if that's an encoding of binary data; you can instead consider hex-encoding it or using modified base-64 for URLs instead - which will not cause errors if mapped as a route parameter.
Upvotes: 4