Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET 4 WebApi: route with back slash

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?

like image 722
Shrike Avatar asked Mar 21 '17 18:03

Shrike


1 Answers

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);
}
like image 138
Shrike Avatar answered Sep 28 '22 03:09

Shrike