ASP.NET Core 9 Minimal API含URL路由部署IIS后无法访问的问题
问题解答
一、如何强制IIS原样转发请求(不做标准化处理)
要让IIS保留浏览器发送的原始编码URL,需修改部署的web.config文件,完成以下两项配置:
允许双转义字符
IIS默认会拦截包含双转义(如%2F)的URL,需在web.config的system.webServer/security/requestFiltering节点开启allowDoubleEscaping:<system.webServer> <security> <requestFiltering allowDoubleEscaping="true"> <!-- 可选:若URL过长,调整最大允许长度 --> <requestLimits maxUrl="4096" maxQueryString="2048" /> </requestFiltering> </security> </system.webServer>禁用URL标准化,转发原始未编码URL
IIS默认会对URL做标准化处理(如解码特殊字符、合并双斜杠),可通过URL重写规则强制使用原始未编码URL转发给ASP.NET Core应用:<system.webServer> <rewrite> <rules> <rule name="Preserve Original Encoded URL" stopProcessing="true"> <match url=".*" /> <action type="Rewrite" url="{UNENCODED_URL}" /> </rule> </rules> </rewrite> </system.webServer>这里的
{UNENCODED_URL}变量会保留浏览器发送的原始编码URL,避免IIS修改后再转发。进程外部署的基础配置
确保web.config中的aspNetCore节点配置正确,无需额外修改,但要避免自定义规则干扰原始URL传递:<aspNetCore processPath="dotnet" arguments=".\YourApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />
二、为何修改后的URL无法匹配ASP.NET Core路由
核心原因是路由参数的默认匹配规则:
- 你定义的路由
/myurl/{url}中,{url}是普通路由参数,默认只会匹配单个路由段(即两个/之间的内容),不会跨越路径分隔符/。 - 当IIS将编码的
http%3A%2F%2Fmydomain.com%2F解码为http:/mydomain.com/后,URL路径被拆分为/myurl/http:/mydomain.com/,此时http:是第一个段,mydomain.com/是第二个段,路由引擎无法找到匹配/myurl/{url}的路由({url}只能匹配到http:,后续的/mydomain.com/没有对应路由定义),因此返回404。 - 独立运行时,URL是编码后的
/myurl/http%3A%2F%2Fmydomain.com%2F,整个http%3A%2F%2Fmydomain.com%2F是单一路由段(无未编码的/),所以{url}可以完整匹配参数,路由正常命中。
额外优化建议
即使解决了IIS的问题,也可以优化路由定义,确保即使出现解码情况也能匹配:将路由参数改为通配符参数(添加*),这样可以匹配多个路由段:
app.MapGet("/myurl/{url*}", MyHandler);
这样{url*}会捕获/myurl/之后的所有内容,包括其中的/,避免出现404问题。
内容的提问来源于stack exchange,提问作者Marcel V.
相关产品推荐
相关产品推荐

