ASP.NET 4 Web Api:带反斜杠的路由

ASP.NET 4 WebApi: route with back slash

我有一个 WebApi 路由 api/{type}({id})/{prop} 我想用 url 来调用它,比如 /api/User(domain\username)/groups - 关键点是 id 值中的“\”。我从客户端发送它 url-encoded 即: api/User(domain%5Cusername)/groups。但是这条路线被忽略了,我得到了 404。

如何将反斜杠传递到路由的参数中?

正如@ATerry 在评论中建议的那样,问题不在于 ASP.NET,而在于 HTTP.SYS + IIS。甚至在进入 IIS 之前,反斜杠被 HTTP.SYS 替换到正斜杠上。
我们可以在 UrlRewrite IIS 模块的帮助下解决这个问题,因为它可以访问原始(未解码)url.

对于我的示例,我提出了以下规则。

<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>

它并不理想,因为它非常具体。拥有一个只处理 %5C.

的通用规则会更有用

想法是用 %5C 捕获一个 url 并重写它以将其放回去。这有点奇怪,但它有效。

除了规则我们还需要在system.webServer/security/requestFiltering中设置allowDoubleEscaping=false:

    <security>
        <requestFiltering allowDoubleEscaping="true">
        </requestFiltering>
    </security>

使用此规则,进入 Mvc/Api 控制器的值将被编码(使用 %)。所以我们必须对其进行解码:

public virtual DomainResult GetObjectProp(string type, string id, string prop)
{
        id = Uri.UnescapeDataString(id);
}