Razor Pages应用中自定义路由返回404错误的原因排查
解决mydomain.com/userName路由到个人页面的404问题
问题根源
- 中间件顺序错误:自定义中间件放在了路由匹配(
UseRouting)之前,导致IEndpointFeature无法获取已匹配的端点,会错误地把现有路由当成用户名处理。 - 路径重写与页面路由不匹配:中间件将路径重写为
/Users/Home,但页面路由是@page "{userName}"(期望路径为/Users/Home/{userName}),两者不匹配引发404。
修复步骤
1. 调整中间件顺序
确保自定义中间件放在app.UseRouting()之后、app.UseEndpoints()之前,才能正确检测已存在的端点:
app.UseRouting(); // 自定义中间件移至此处 app.Use(async (context, next) => { var path = context.Request.Path.Value; if (!string.IsNullOrEmpty(path) && path != "/" && !path.Contains(".")) { var endpointFeature = context.Features.Get<IEndpointFeature>(); if (endpointFeature?.Endpoint == null) { using var scope = app.Services.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); var userName = path.TrimStart('/'); var performer = await dbContext.Users.FirstOrDefaultAsync(u => u.UserName == userName); if (performer != null) { // 修改路径重写为页面期望的路由格式 context.Request.Path = $"/Users/Home/{userName}"; await next(); return; } } } await next(); }); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); // 其他端点配置 });
2. 保留页面路由配置
Users/Home.cshtml顶部维持原有配置:
@page "{userName}"
Users/Home.cshtml.cs的OnGetAsync无需修改,路由会自动将路径中的userName绑定到方法参数:
public async Task<IActionResult> OnGetAsync(string userName) { var performer = await DbContext.Users.FirstOrDefaultAsync(u => u.UserName == userName); return Page(); }
替代方案(不修改路径格式)
如果不想调整重写后的路径,可将页面路由改为@page "",通过RouteData获取参数:
Users/Home.cshtml:@page ""Users/Home.cshtml.cs:public async Task<IActionResult> OnGetAsync() { var userName = RouteData.Values["userName"]?.ToString(); var performer = await DbContext.Users.FirstOrDefaultAsync(u => u.UserName == userName); return Page(); }- 中间件保留
context.Request.Path = "/Users/Home";和context.Request.RouteValues["userName"] = userName;配置。
额外注意事项
- 避免用户名与现有路由冲突(比如不能有用户名为
Users的用户,否则会优先匹配/Users路由)。 - 可在中间件中添加用户名格式校验,减少无效数据库查询。
内容的提问来源于stack exchange,提问作者jbassking10
相关产品推荐
相关产品推荐

