ASP.NET 3.5路由含*、:等特殊字符触发400.0 Bad Request问题咨询
问题根因
.NET Framework 3.5 原生的 ASP.NET 路由模块默认会将路径中包含*、:等保留字符的请求直接判定为非法,在路由匹配阶段就拦截返回400错误,且编码后的特殊字符会被IIS/ASP.NET先解码再做校验,所以转义后访问依然会触发错误。你查询到的relaxedUrlToFileSystemMapping等修复配置是.NET Framework 4.0及以上版本新增的,3.5版本原生不支持。
适配.NET Framework 3.5的修复方案
方案1:使用Catch-All路由+路径校验配置(仅需3.5安装SP1补丁即可使用)
这是改动最小的方案,.NET Framework 3.5 SP1 版本已经支持requestPathInvalidCharacters配置项,可以自定义放行的路径字符。
- 修改路由注册代码,使用Catch-All路由参数捕获完整的后缀路径,绕过原生的路由参数字符校验:
private void RegisterRoutes(RouteCollection routes) { CustomRouteHandler x = new CustomRouteHandler("~/page.aspx"); // {*text} 为catch-all格式,会匹配mypath/之后的所有路径内容,包括含特殊字符的片段 routes.Add("mypath",new Route("mypath/{*text}", x)); }
- 修改web.config配置,从默认的非法路径字符列表中移除
*和::
<system.web> <!-- 原生默认值为 <,>,*,%,&,:,\,?,此处删除了*和:两个字符即可放行对应参数 --> <httpRuntime requestPathInvalidCharacters="<,>,%,&,\,?" /> </system.web>
方案2:自定义HttpModule预处理请求(无版本依赖,未安装SP1也可使用)
如果你的3.5版本没有安装SP1,不支持上述配置,可以通过自定义HttpModule在路由校验前替换特殊字符,到业务页面再还原。
- 新增自定义HttpModule实现:
public class SpecialCharProcessModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += (sender, e) => { var app = (HttpApplication)sender; var rawUrl = app.Request.RawUrl; // 仅处理目标路由前缀的请求 if (!rawUrl.StartsWith("/mypath/", StringComparison.OrdinalIgnoreCase)) return; // 替换特殊字符为自定义占位符,避免路由校验拦截 var processedUrl = rawUrl.Replace("*", "[ASTERISK_PLACEHOLDER]").Replace(":", "[COLON_PLACEHOLDER]"); app.Context.RewritePath(processedUrl); }; } public void Dispose() { } }
- 在web.config中注册这个模块:
<!-- IIS6/经典模式注册位置 --> <system.web> <httpModules> <add name="SpecialCharProcessModule" type="你的项目命名空间.SpecialCharProcessModule, 你的程序集名称"/> </httpModules> </system.web> <!-- IIS7+集成模式注册位置 --> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="SpecialCharProcessModule" type="你的项目命名空间.SpecialCharProcessModule, 你的程序集名称"/> </modules> </system.webServer>
- 在业务页面取参数时还原特殊字符:
string text = RouteData.Values["text"]?.ToString() ?? string.Empty; text = text.Replace("[ASTERISK_PLACEHOLDER]", "*").Replace("[COLON_PLACEHOLDER]", ":");
注意事项
- Catch-all路由必须放在相同路径前缀的其他路由规则之后,避免影响其他路由的正常匹配
- 放行特殊字符后要做好参数的合法性校验,避免路径遍历、注入等安全风险
内容的提问来源于stack exchange,提问作者mvaculisteanu
相关产品推荐
相关产品推荐

