ASP.Net Core 7.0 MVC全局错误处理:ErrorViewModel的OnGet/OnPost未触发
ASP.NET Core 7.0 MVC全局错误处理问题解决方案
问题根源
你混淆了MVC控制器视图和Razor Page的实现逻辑:
- 配置
app.UseExceptionHandler("/Home/Error")是指向MVC控制器的Action,而非Razor Page - 让
ErrorViewModel继承PageModel并添加OnGet/OnPost方法是Razor Page的写法,和MVC的视图模型逻辑不匹配 - 添加
@page会把视图转为Razor Page,脱离MVC控制器的上下文,导致ViewData失效
修复步骤
1. 还原ErrorViewModel为普通MVC视图模型
删除PageModel继承、OnGet/OnPost方法以及Razor Page相关特性:
public class ErrorViewModel { public string? RequestId { get; set; } public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); // 新增异常信息属性 public Exception? Exception { get; set; } public string? ExceptionMessage { get; set; } }
2. 修改HomeController的Error Action获取异常信息
在HomeController中添加Error方法,通过IExceptionHandlerPathFeature捕获未处理的异常:
using Microsoft.AspNetCore.Diagnostics; public class HomeController : Controller { // ... 其他方法 [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [IgnoreAntiforgeryToken] public IActionResult Error() { // 获取异常处理特性 var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>(); var viewModel = new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, Exception = exceptionFeature?.Error, ExceptionMessage = exceptionFeature?.Error?.Message }; return View(viewModel); } }
3. 确保Program.cs的中间件顺序正确
中间件顺序会影响错误处理逻辑,确保UseExceptionHandler在UseRouting和UseAuthorization之前:
var builder = WebApplication.CreateBuilder(args); // 添加服务 builder.Services.AddControllersWithViews(); var app = builder.Build(); // 全局错误处理中间件(必须在路由之前) app.UseExceptionHandler("/Home/Error"); app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
4. 调整Shared/Error.cshtml视图
移除@page指令,确保视图绑定到ErrorViewModel并展示异常信息:
@model ErrorViewModel @{ ViewData["Title"] = "Error"; } <h1 class="text-danger">Error.</h1> <h2 class="text-danger">An error occurred while processing your request.</h2> @if (Model.Exception != null) { <div class="alert alert-danger"> <h3>Exception Details:</h3> <p>@Model.ExceptionMessage</p> @if (!string.IsNullOrEmpty(Model.RequestId)) { <p>Request ID: <code>@Model.RequestId</code></p> } </div> } <p>If you are unable to resolve this error, please contact the support team.</p>
测试验证
在HomeController的Index方法中抛出异常测试:
[HttpGet] public IActionResult Index() { throw new ApplicationException("测试全局错误处理"); }
运行项目后访问首页,会自动跳转到错误页并展示异常信息。
内容的提问来源于stack exchange,提问作者Rob K.
相关产品推荐
相关产品推荐

