Brandon Rader
Brandon Rader

Reputation: 976

.NET Web API Slash in Route

I have a .NET Web API v2 and need to define a route that can contain forward slashes at any point in the route. I have it configured (something) like this in WebApiConfig:

config.Routes.MapHttpRoute(
    name: "SomeRouteName",
    routeTemplate: "api/summary/{*token}",
    defaults: new { controller = "Summary" });

Unfortunately the token contains slashes and there's nothing I can do about it at this point. The above route works in most cases if the slash is not at the beginning of the token. So that takes care of most cases. But if token begins with slash(es), it doesn't work because that first slash gets interpreted as part of the URL I assume and gets eaten. So in my controller action, I have the following code (admittedly a hack that I'm trying to avoid):

if (summary == null)
{
    summary = _repo.GetSummary($"/{token}");
}

Obviously, this will only work for a single slash. I could do a loop and add more, but there isn't way to know how many it could be. Currently no tokens in my DB begin with two slashes, so this bad code works for now. It was implemented as a band-aid until a better solution is found.

Edit: This references the * route, which mostly fixed my original issue, but still doesn't match the first slashes: URLs with slash in parameter?

Upvotes: 1

Views: 3256

Answers (1)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64923

Since OP said in some comment:

There is no purpose -- but the tokens are generated and not necessarily by my code. So I don't have control over the token generation.

and also:

I've attempted to UrlEncode /Decode to see if this works, but the slash (encoded as %2F) still gets eaten for whatever reason. As a side note, I can say that Base64 encoding it will fix this but that I can't change this at this point because it would break the API for existing apps.

I would say that one of best choices to avoid issues with special characters is firstly encoding the whole token as a base 64 string, and then url-encode it to encode possible characters like =.

That is, you can configure a route where you don't need {token*} but just {token}. If you need to simplify the token decoding, you can implement an ActionFilterAttribute that decodes the so-called bound parameter under the hoods.

Others have already done this way...

OAuth2 already sends basic authentication's credentials encoding them as a base64 string (you convert user:password to the whole base 64 string).

It's a common way of avoding these issues and base 64 strings can be decoded in every modern client and server platform.

Upvotes: 1

Related Questions