Draganov
Draganov

Reputation: 375

URL encoded params handling with ASP.NET MVC

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

Answers (1)

Andras Zoltan
Andras Zoltan

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

Related Questions