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

ASP.NET Core未用UseDeveloperExceptionPage却出现开发者异常页问题

ASP.NET MVC 自定义错误页异常问题

项目修改说明

这是一个基于模板创建的简单MVC项目,已修改以下文件:

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseExceptionHandler("/Home/Error");

if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

HomeController.cs(Privacy和Error方法)

public IActionResult Privacy()
{
    throw new Exception("Exception message");
    return View();
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
    HttpContext.Response.StatusCode = StatusCodes.Status404NotFound;
    var contextFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();

    return View(new ErrorViewModel { Message = contextFeature!.Error.Message });
}

问题描述

项目运行在开发模式(IIS Express)下,访问Privacy方法触发异常后,自定义错误页下方会额外显示开发者异常页,但项目中并未调用UseDeveloperExceptionPage()。该问题仅在Error方法中设置HttpContext.Response.StatusCode = StatusCodes.Status404NotFound时出现,设置其他状态码则能正常显示自定义错误页。

问题原因

  1. 开发模式下,ASP.NET Core默认中间件对404状态码存在特殊处理逻辑:当响应状态码为404时,即便已通过UseExceptionHandler处理了异常,后续中间件(如静态文件中间件)仍会尝试查找匹配资源,未找到时会触发默认的开发者404错误页,导致与自定义错误页叠加显示。
  2. 在Error方法中直接设置404状态码后,响应未被标记为已完成,后续中间件仍能介入处理流程。

解决办法

方法1:修改Error方法,确保响应处理完成

在设置状态码前先清除现有响应,避免后续中间件干扰:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
    var contextFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
    
    // 清除响应内容,标记响应已开始处理
    HttpContext.Response.Clear();
    HttpContext.Response.StatusCode = StatusCodes.Status404NotFound;
    
    return View(new ErrorViewModel { Message = contextFeature!.Error.Message });
}

方法2:使用NotFound()结果替代手动设置状态码

通过返回NotFoundObjectResult来设置404状态码,ASP.NET Core会自动处理响应完成逻辑:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
    var contextFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
    var model = new ErrorViewModel { Message = contextFeature!.Error.Message };
    
    return NotFound(model);
}

需确保Error视图能正常接收并显示ErrorViewModel的数据。

方法3:调整中间件配置,统一处理状态码

在Program.cs中添加UseStatusCodePagesWithReExecute,优先处理状态码异常,同时保持异常处理中间件的优先级:

var app = builder.Build();

// 先添加状态码页面处理
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
app.UseExceptionHandler("/Home/Error");

// 其他中间件配置...

然后修改Error方法接收状态码参数:

public IActionResult Error(int? statusCode)
{
    var contextFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
    var model = new ErrorViewModel 
    { 
        Message = contextFeature?.Error?.Message ?? $"状态码: {statusCode}"
    };
    
    HttpContext.Response.StatusCode = statusCode ?? StatusCodes.Status500InternalServerError;
    return View(model);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:13:00