1

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?

Community
  • 1
  • 1
Brandon Rader
  • 916
  • 9
  • 24
  • Isn't UrlEnconding/Decoding this token possible? – Bruno Garcia Mar 30 '16 at 18:45
  • And what's the purpose of having many slashes at the beginning of `token`? – Matías Fidemraizer Mar 30 '16 at 18:46
  • @bruno-garcia 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. – Brandon Rader Mar 30 '16 at 18:48
  • @Matias 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. – Brandon Rader Mar 30 '16 at 18:49

1 Answers1

1

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.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • I agree that base 64 encoding it would solve it, but I'm hoping to find a routing / configuration solution as I'm not able to change it. I've brought up that it should be base 64 encoded, but the decision was made not to do that. I can't make my consumers change their code at this point either. – Brandon Rader Mar 30 '16 at 19:04
  • @BrandonRader Well, if you/we find a better solution, I'll update my answer... for now, it seems that there's no more workaround than this... – Matías Fidemraizer Mar 30 '16 at 19:05
  • @BrandonRader Maybe an action filter or custom parameter binding can do the trick... – Matías Fidemraizer Mar 30 '16 at 19:06
  • @BrandonRader Another approach might be giving this token as a query string parameter instead of part of the path............. BTW, this also forces your customers to change their code.... – Matías Fidemraizer Mar 30 '16 at 20:03
  • @BrandonRader I'm not sure, but maybe your issue can be solved using URL-rewriting. For example, I'm not sure, but maybe IIS or whatever web server you're currently using can map the path with token without encoding it to a route where the token is rewritten as query string parameter... – Matías Fidemraizer Mar 30 '16 at 20:04
  • I encoded it in base 64, which was my original solution as well (before I was told not to do it... sigh) so I'm marking this as the answer. – Brandon Rader Jun 16 '16 at 20:19
  • @BrandonRader Sometimes we're not mistaken about our approaches ;P – Matías Fidemraizer Jun 17 '16 at 08:16