You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC中UseStatusCodePagesWithReExecute状态码传0问题

ASP.NET Core 7 MVC自定义错误页面状态码传递异常问题

问题描述

在为ASP.NET Core 7 MVC + ASP.NET MVC 5实现404、500错误自定义处理逻辑时,已配置错误控制器及视图,尝试使用UseStatusCodePagesWithReExecute中间件,但错误控制器始终收到状态码0,而非实际的HTTP状态码(如404)。

相关代码

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// MVC
if (builder.Environment.IsDevelopment())
    builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation(); //for debugging views
else
    builder.Services.AddControllersWithViews();

// Add services to the container.
// Blazor
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(15);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });

//Mudblazor UI Lib
//builder.Services.AddMudServices();

//connstring configs
builder.Services.Configure<AppSettings>(
    builder.Configuration.GetSection("ConnectionStrings"));

//EF registrations
builder.Services.AddDbContext<ArticlesContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("ArticleDBconnectionString")));
builder.Services.AddDbContext<ProductContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("ProductsConnection")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");    
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();    
}

//app.UseStatusCodePages();

app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseMiddleware<ViewNotFoundExceptionMiddleware>();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

//Razor config
app.MapRazorPages();
app.MapBlazorHub();

//mvc config
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

ErrorController.cs

[AllowAnonymous]
public class ErrorController : Controller
{
    
    [Route("/Error/{code}")]
    new public ActionResult NotFound(int StatusCode)
    {            
        var errorFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
        var error = errorFeature?.Error;
        ViewBag.ErrorMsg = "404 Page not found please try again XD";
        return View("Error", ViewBag);
    }

    [Route("/Error")]
    public ActionResult Error(int StatusCode)
    {
        var errorFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
        var error = errorFeature?.Error;
        ViewBag.ErrorMsg = "500 Server Error please try again XD";
        return View();
    }
}

问题原因及解决方案

1. 路由参数与控制器参数不匹配

UseStatusCodePagesWithReExecute("/Error/{0}")中的{0}会被替换为实际HTTP状态码,传递到路由的占位符中。但你的控制器方法:

  • 路由是/Error/{code},占位符名为code
  • 方法参数名为StatusCode

模型绑定无法将code映射到StatusCode,因此参数默认值0被传入。

修正方案:
统一路由占位符名称与方法参数名称,例如:

[Route("/Error/{statusCode}")]
public ActionResult StatusCodeError(int statusCode)
{
    ViewBag.ErrorMsg = statusCode switch
    {
        404 => "404 页面未找到,请重试 XD",
        500 => "500 服务器错误,请重试 XD",
        _ => $"HTTP {statusCode} 错误"
    };
    return View("Error");
}

2. 混淆异常处理与状态码处理逻辑

UseStatusCodePagesWithReExecute用于处理非异常导致的HTTP状态码(如路由不存在的404),而IExceptionHandlerFeature仅在UseExceptionHandler的异常处理流程中存在,在状态码处理方法中获取不到该Feature,属于无效逻辑。

修正方案:
拆分控制器方法,分别处理状态码和未捕获异常:

// 处理状态码页面(如404、403)
[Route("/Error/{statusCode}")]
public ActionResult StatusCodeError(int statusCode)
{
    // 状态码相关逻辑
    return View("Error");
}

// 处理未捕获异常(由UseExceptionHandler跳转)
[Route("/Error")]
public ActionResult ExceptionError()
{
    var errorFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
    var error = errorFeature?.Error;
    ViewBag.ErrorMsg = "服务器发生未处理异常,请重试 XD";
    // 可添加日志记录逻辑
    return View("Error");
}

3. 中间件顺序错误

UseStatusCodePagesWithReExecute需要放在UseRouting之前,才能正确拦截状态码并重新执行请求。同时自定义的ViewNotFoundExceptionMiddleware可能会提前处理404请求,导致UseStatusCodePagesWithReExecute无法生效。

修正方案:
调整中间件顺序,移除或调整自定义中间件位置:

if (app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");    
    app.UseHsts();    
}

// 放在UseRouting之前
app.UseStatusCodePagesWithReExecute("/Error/{0}");
// 若自定义中间件需保留,移至UseStatusCodePagesWithReExecute之后
// app.UseMiddleware<ViewNotFoundExceptionMiddleware>();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

// 后续路由映射...

内容的提问来源于stack exchange,提问作者d0rf47

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:45:38