I have the option to pass strings as URI parameters, but when this string contains a special character like '/' the routing will break. How do I avoid this?
I thought of passing strings always (or when they contain a special character) Url Encoded, but unfortunately the Web API does not automatically decode this string (what I would have expected). Always decoding this myself in the method is a no-go for me.
How is the correct way to solve this? And how could I plug myself in right before the string parameters are filled, so I can decode the string myself?
I understand what's the problem with passing special characters and I know Url Encoding, that's absolutely clear to me. What's unclear is how to make this work with the Web API. When I pass in an Url encoded string as a parameter, I get the Url encoded string
within my method. I don't want to manually decode this string myself.
In the self host case, what is happening is that the Http.SYS layer would decode the url string, and the web API routing layer would construct a Uri based on that decoded string, and Uri would encode some reserved character by default. So at the web api
runtime, we would decode the character one more time. In some cases, the reservered character would not be encoded by Uri, then you will see some weird behavior.
For the '/' case, because Http.SYS would turn %20 into /, the routing would think this is / rather than a string. so it might match your route correctly.
~/Hello%20World/123 would turn it into Hello/World, if your route templates look like "/{message}/{id}", "Hello World" would not map to the message route parameter.
There is a simple work around for this issue if this is self host. The following configuration will let HttpListener use the undecoded url.
<system.net>
<settings>
<httpListener
unescapeRequestUrl="false"
/>
</settings>
</system.net>
If this is web hosted case, then url string is decoded by the HTTP.SYS layer, and then it become "hello/world" and the routing layer would see "Hello/World" as two url segments. There is no good workaround for this issue unfortunately except double encoding
the "/", then you will need to decode in your controller layer.
In the self host case, what is happening is that the Http.SYS layer would decode the url string, and the web API routing layer would construct a Uri based on that decoded string, and Uri would encode some reserved character by default. So at the web api
runtime, we would decode the character one more time. In some cases, the reservered character would not be encoded by Uri, then you will see some weird behavior.
For the '/' case, because Http.SYS would turn %20 into /, the routing would think this is / rather than a string. so it might match your route correctly.
~/Hello%20World/123 would turn it into Hello/World, if your route templates look like "/{message}/{id}", "Hello World" would not map to the message route parameter.
There is a simple work around for this issue if this is self host. The following configuration will let HttpListener use the undecoded url.
<system.net>
<settings>
<httpListener
unescapeRequestUrl="false"
/>
</settings>
</system.net>
If this is web hosted case, then url string is decoded by the HTTP.SYS layer, and then it become "hello/world" and the routing layer would see "Hello/World" as two url segments. There is no good workaround for this issue unfortunately except double encoding
the "/", then you will need to decode in your controller layer.
Let me know if this clarifies.
best,
Hongmei
Marked as answer by MartinJ. on Jan 20, 2013 08:50 AM
If this is web hosted case, then url string is decoded by the HTTP.SYS layer, and then it become "hello/world" and the routing layer would see "Hello/World" as two url segments. There is no good workaround for this issue unfortunately except double encoding
the "/", then you will need to decode in your controller layer.
Hello Hongmei. This is my exact problem, and I think it's very bad that there is not a propert solution existing for this. This essentially makes string parameters in the Uri useless in my opinion.
I'll mark your response as the answer, but I still hope someone has a better idea of how to solve this. It is very unsatisfying to either forbid string parameters, or double encode the string and manually decode it inside the method.
MartinJ.
Member
243 Points
80 Posts
Pass special characters within URI
Jan 17, 2013 05:14 PM|LINK
Hello!
I have the option to pass strings as URI parameters, but when this string contains a special character like '/' the routing will break. How do I avoid this?
I thought of passing strings always (or when they contain a special character) Url Encoded, but unfortunately the Web API does not automatically decode this string (what I would have expected). Always decoding this myself in the method is a no-go for me.
How is the correct way to solve this? And how could I plug myself in right before the string parameters are filled, so I can decode the string myself?
Thanks for any answers!
mebinici
Participant
815 Points
256 Posts
Re: Pass special characters within URI
Jan 17, 2013 05:28 PM|LINK
Take a look at this lenghy explaination.
Reserved keywords, chars, etc.,
A couple methods to work around this.
http://stackoverflow.com/questions/2366260/whats-valid-and-whats-not-in-a-uri-query
then
http://forums.asp.net/t/1294449.aspx
Love collecting video games, movies and board games!
Enjoying my '11 WRX, so sexy...
MartinJ.
Member
243 Points
80 Posts
Re: Pass special characters within URI
Jan 18, 2013 07:16 AM|LINK
I understand what's the problem with passing special characters and I know Url Encoding, that's absolutely clear to me. What's unclear is how to make this work with the Web API. When I pass in an Url encoded string as a parameter, I get the Url encoded string within my method. I don't want to manually decode this string myself.
Neither of your links helps me with this issue.
Hongmei Ge
Member
26 Points
8 Posts
Microsoft
Re: Pass special characters within URI
Jan 18, 2013 05:30 PM|LINK
Dear Martin,
Thank you for reporting this issue. This might be related a known issue tracked by http://aspnetwebstack.codeplex.com/workitem/607.
In the self host case, what is happening is that the Http.SYS layer would decode the url string, and the web API routing layer would construct a Uri based on that decoded string, and Uri would encode some reserved character by default. So at the web api runtime, we would decode the character one more time. In some cases, the reservered character would not be encoded by Uri, then you will see some weird behavior.
For the '/' case, because Http.SYS would turn %20 into /, the routing would think this is / rather than a string. so it might match your route correctly.
~/Hello%20World/123 would turn it into Hello/World, if your route templates look like "/{message}/{id}", "Hello World" would not map to the message route parameter.
There is a simple work around for this issue if this is self host. The following configuration will let HttpListener use the undecoded url.
<system.net>
<settings>
<httpListener
unescapeRequestUrl="false"
/>
</settings>
</system.net>
If this is web hosted case, then url string is decoded by the HTTP.SYS layer, and then it become "hello/world" and the routing layer would see "Hello/World" as two url segments. There is no good workaround for this issue unfortunately except double encoding the "/", then you will need to decode in your controller layer.
Let me know if this clarifies.
best,
Hongmei
Hongmei Ge
Member
26 Points
8 Posts
Microsoft
Re: Pass special characters within URI
Jan 18, 2013 05:31 PM|LINK
Dear Martin,
Thank you for reporting this issue. This might be related a known issue tracked by http://aspnetwebstack.codeplex.com/workitem/607.
In the self host case, what is happening is that the Http.SYS layer would decode the url string, and the web API routing layer would construct a Uri based on that decoded string, and Uri would encode some reserved character by default. So at the web api runtime, we would decode the character one more time. In some cases, the reservered character would not be encoded by Uri, then you will see some weird behavior.
For the '/' case, because Http.SYS would turn %20 into /, the routing would think this is / rather than a string. so it might match your route correctly.
~/Hello%20World/123 would turn it into Hello/World, if your route templates look like "/{message}/{id}", "Hello World" would not map to the message route parameter.
There is a simple work around for this issue if this is self host. The following configuration will let HttpListener use the undecoded url.
<system.net>
<settings>
<httpListener
unescapeRequestUrl="false"
/>
</settings>
</system.net>
If this is web hosted case, then url string is decoded by the HTTP.SYS layer, and then it become "hello/world" and the routing layer would see "Hello/World" as two url segments. There is no good workaround for this issue unfortunately except double encoding the "/", then you will need to decode in your controller layer.
Let me know if this clarifies.
best,
Hongmei
MartinJ.
Member
243 Points
80 Posts
Re: Pass special characters within URI
Jan 20, 2013 08:50 AM|LINK
Hello Hongmei. This is my exact problem, and I think it's very bad that there is not a propert solution existing for this. This essentially makes string parameters in the Uri useless in my opinion.
I'll mark your response as the answer, but I still hope someone has a better idea of how to solve this. It is very unsatisfying to either forbid string parameters, or double encode the string and manually decode it inside the method.