ASP.NET Core 3.0接口含+的邮箱路由参数在Azure中异常
解决Azure Web App上ASP.NET Core 3.0 API带+号邮箱路由返回404的问题
这问题我之前帮同事排查过,核心原因是Azure Web App的IIS托管层会默认把URL中的+符号解析为空格,导致你的路由匹配失败——请求根本没到达你的API控制器,就被Azure的前端拦截返回了自带的404页面。
问题分析
- 本地用Kestrel服务器运行时,Kestrel默认允许URL中的特殊字符(包括+号),所以路由
/api/employees/jane.doe+test@mail.com能正常匹配到你的控制器方法; - 部署到Azure后,Web App用IIS托管,IIS默认的
requestFiltering配置中allowDoubleEscaping是false,+号会被自动转成空格,此时请求路径变成/api/employees/jane.doe test@mail.com,自然匹配不到你的路由规则,返回Azure自带的404。
解决方案
1. 修改Web.config开启允许双重转义
如果你的项目部署后生成了Web.config(ASP.NET Core部署到IIS/Azure时会自动生成),手动添加或修改<security>节点:
<system.webServer> <!-- 其他已有配置 --> <security> <requestFiltering allowDoubleEscaping="true" /> </security> </system.webServer>
这个配置会告诉IIS不要自动转义URL中的特殊字符,让请求原封不动地传递到你的API。
2. 确保ASP.NET Core路由允许特殊字符
在Startup.cs的ConfigureServices方法中,配置路由选项允许Unicode字符和特殊符号:
services.AddControllers(options => { // 允许路由参数包含Unicode和特殊字符(如+号) options.RouteOptions.AllowUnicode = true; // 可选:如果需要更严格的邮箱格式验证,可以自定义路由约束 });
如果需要对邮箱参数做格式校验,可以自定义一个路由约束:
public class EmailRouteConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (values.TryGetValue(routeKey, out var value) && value is string email) { // 简单的邮箱格式验证,允许+号存在于本地部分 return Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"); } return false; } }
然后在ConfigureServices中注册这个约束:
services.AddControllers(options => { options.RouteOptions.ConstraintMap["email"] = typeof(EmailRouteConstraint); });
最后在路由配置中使用这个约束:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "GetEmployeeByEmail", pattern: "api/employees/{email:email}", defaults: new { controller = "Employees", action = "GetByEmail" }); });
3. 验证部署
把修改后的代码和Web.config部署到Azure Web App,再次测试带+号的邮箱请求,此时请求应该能正常到达你的API控制器,返回预期的员工数据,而不是Azure自带的404。
内容的提问来源于stack exchange,提问作者JuChom
相关产品推荐
相关产品推荐

