I have a WebApi-route api/{type}({id})/{prop}
and I want to call it with url like /api/User(domain\username)/groups
- the key point is "\" in id
value. I send it from the client url-encoded i.e. as:
api/User(domain%5Cusername)/groups
. But the route is ignored and I'm getting 404.
How to pass back slash into a route's argument?
As @ATerry suggested in comments the problem is not with ASP.NET but in HTTP.SYS + IIS. Back-slashes are replaced by HTTP.SYS onto forward-slashes even before coming to IIS.
We can work this around with help of UrlRewrite IIS-module as it has access to original (undecoded) url.
For my example I came up with the following rule.
<rule name="allow backslash" stopProcessing="true">
<match url="api/(.*)\((.*)\)(.*)" />
<action type="Rewrite" url="api/{R:1}({C:1}{C:2}{C:3}){R:3}" logRewrittenUrl="true" />
<conditions>
<add input="{UNENCODED_URL}" pattern="\((.*)(%5C)(.*)\)" />
</conditions>
</rule>
It's not ideal as it's very specific. It'd more useful to have a generic rule which just processes %5C
.
The idea is to catch an url with %5C
and rewrite it to put it back. It's a little bit weird but it works.
Besides the rule we need to set allowDoubleEscaping=false
in system.webServer
/security
/requestFiltering
:
<security>
<requestFiltering allowDoubleEscaping="true">
</requestFiltering>
</security>
With this rule the value come into a Mvc/Api controller will be encoded (with %). So we'll have to decode it:
public virtual DomainResult GetObjectProp(string type, string id, string prop)
{
id = Uri.UnescapeDataString(id);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With