2

I have a very simple webservice with one GET method that has a token string parameter. I use this token can have letters, "+" and "/". Ex.: mC1SW7RJhgsQGtRHhsg/Q+FGoZjbBleNKtpqT7zLMtE

I use this token to look in the database if there is data for this token.

My method in the controller is like that:

[HttpGet("{token}")] [ProducesResponseType(typeof(string), 200)] [ProducesResponseType(typeof(void), 404)] public JsonResult Get(string token) { string sql = "SELECT dataObject FROM Session WHERE id = @SessionToken"; var data = _conn.QueryFirstOrDefault<Session>(sql, new {SessionToken = token}); if (data == null){ var r = Json(string.Empty); r.StatusCode = StatusCodes.Status404NotFound; return r; } else { return Json(JsonConvert.DeserializeObject(data.dataObject)); } } 

I see Dapper/Webapi automatically escapes this parameter and change "/" to "%2F" for example.

When I deploy it just works for tokens without special characters and return 404.

As a workaround I changed the token in the server to encode the token and replace the encoded plus sign to space:

string decodedToken = WebUtility.UrlDecode(token); token = decodedToken.Replace(" ", "+"); 

The problem is that I need my clients to do the inverse and replace the '+' sign:

var encodedToken = WebUtility.UrlEncode(token); // Convert '+' to ' ' token = encodedToken.Replace("%2B", " "); 

What is the recommended way to work without asking the client to replace de '+' signs?

1
  • If you control the token that they receive, you can Encode it when you deliver the token to them in the first place? stackoverflow.com/questions/26353710/… Commented Sep 24, 2019 at 20:11

2 Answers 2

1

For some reason Kestrel or .NET MVC do a partial decode in a encoded URL. This looks like a BUG (https://github.com/aspnet/Mvc/issues/6388), but there is a workaround.

With the token you passed in question you would encode it in the client:

 Original Token: mC1SW7RJhgsQGtRHhsg/Q+FGoZjbBleNKtpqT7zLMtE Encoded Token: mC1SW7RJhgsQGtRHhsg%2FQ%2BFGoZjbBleNKtpqT7zLMtE 

See that '/' became '%2F' and '+' became '%2B'. This is because these two characters are part of the composition of a URL. Therefore to pass them fully to WebApi they must be replaced with their ASCII representation.

You would call your service with the encoded token like this:

 http://myserver:1234/myservice/token/mC1SW7RJhgsQGtRHhsg%2FQ%2BFGoZjbBleNKtpqT7zLMtE 

In your service, because of the bug, you would receive from Kestrel/MVC the following string partially decoded:

 Partially decoded token: mC1SW7RJhgsQGtRHhsg%2FQ+FGoZjbBleNKtpqT7zLMtE 

Just implement a simple replace:

 token.Replace("%2F", "/"); 

And your string will be full decoded.

Sign up to request clarification or add additional context in comments.

Comments

0

Try to add below code in your web.config:

<system.webServer> <security> <requestFiltering allowDoubleEscaping="true" /> </security> </system.webServer> 

Refer to Dotnet core + (plus) sign in Web API routing

2 Comments

It is dotnetcore. This does not apply.
@StaticX This link is for asp.net core publish to IIS, have you try that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.