The rights of my users are at /api/admin/users/{userId}/rights
And my controller is as simple as
[Route("/api/admin/users/{userId}/rights")]
public async Task<IActionResult> GetRights([FromRoute]string userId)
{
var rights = await _someService.GetRights(userId);
return Ok(rights);
}
or
[HttpPut("{userId}")]
public async Task<IActionResult> Update(string userId, [FromBody]UpdateUserViewModel parameters)
{
var user = await _employeService.Update(userId, parameters);
return Ok(user);
}
The problem I have is that, the userIds of my users may contains a / which is encoded to %2F in the Uri. But userId doesn't decode %2F so my string contains %2F. It's fine for me, I can deal with that.
But the userIds of my users may contains a + which is encoded to %2B in the Uri. And now, the userId decode the %2B to + 馃槻
Currently, I can't use WebUtility.UrlDecode(userId) because userId may contains a + which would be send as %2B decoded as + and finally to . My only actual solution is to replace %2F to / which is ugly and does not solve all the possibility : %252F
I saw a recommandation to use [FromQuery] instead of [FromRoute] but it's obvious that if both exist, it's because they have semantic difference.
It seems that's not the first time the problem appears : https://github.com/aspnet/Mvc/issues/4599, https://github.com/aspnet/AspNetCore/issues/2655, https://github.com/aspnet/AspNetCore/issues/4445 and I'd like to know if it's on the roadmap to change this behavior or not.
Could you please this time consider this bug ? I'd be happy to help.
Thanks for contacting us, @SchroterQuentin.
We'll provide an option so that FromRoute attribute decodes specific (by you) parameters.
The problem exist on [HttpGet] [HttpPost] [HttpPut] etc. Is there a way to handle all this problems in one area ? Or do we have to add this options on all this attributes ?
I'm actually not understanding how would work this option ?
Also see aspnet/Mvc#6388
The hosts partially decodes the percent encoding and explicitly skips decoding %2F here:
Microsoft.AspNetCore.Server.IIS > Microsoft.AspNetCore.HttpSys.Internal.RequestUriBuilder.UnescapePercentEncoding
Microsoft.AspNetCore.Server.HttpSys > Microsoft.AspNetCore.HttpSys.Internal.RequestUriBuilder.UnescapePercentEncoding
Microsoft.AspNetCore.Server.Kestrel.Core > Microsoft.AspNetCore.Internal.UrlDecoder.UnescapePercentEncoding
The main problem is Routing or MVC model binding cannot reliably decode the partially decoded segment. Ideally the server should not do any decoding especially not partial. (Full decoding is not possible since it would introduce new segments.)
If the server behavior is not allowed to change (even behind a compatibility flag) then the router middleware could be modified to use the raw request url from IHttpRequestFetaure.RawTarget (which is not yet decoded) to get proper encoded tokens then decode as needed.
A possible workaround: inject a middleware before routing takes place that restores the original undecoded path from IHttpRequestFeature.RawTarget then in another middleware after routing decode the RouteData tokens.
As part of doing this, ensure binding to non-string values that require decoded values work. See https://github.com/aspnet/AspNetCore/issues/11134
Can we get an update on this? I just spent half an hour debugging my API before I found out that Route parameters are not URL decoded by default.
Yeah, this behaviour is pretty _weird_.
If you can't fix it then this FromRouteAttribute option would be a good compromise for me. Or perhaps provide an example implementation of the middleware suggested by https://github.com/Eilon in https://github.com/aspnet/Mvc/issues/6388
I see that this bug lives since at least 2017 and there is not even a workaround about it.
In .Net Core you don't allow us to do WCF anymore, so we are forced to do REST.
In REST we need to send parameters via Route, not via Query.
So we need to use [FromRoute], which should happen short before Model-Binding, but definitely after Routing.
So there is no worry about decoding %2B into /.
Then why is nothing happening here?
You closed any other Issues (at least 4 peaces counted) and now you let this open for loooong time.
How many developers do you need to comment on this issue, before you consider it worthy to look upon?
Can we get an update on this?
We will consider fixing this in the upcoming 5.0 release. That said, the plan is to not have this decoding on by default - you explicitly would have to opt-in to this behavior. For current releases, you should be able to unblock yourselves by explicitly url decoding values in your action that you know require to be decoded.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.