c# - ASP.NET Core MVC (2.2) 错误中间件未触发错误页面
问题描述
在我的 ASP.NET Core MVC (2.2) 应用程序中,我已经完成了全局错误处理类的设置。我通过app.UseMiddleware()
在app.UseMvc()
. 这个错误处理程序会在每个异常上触发,但是,当我将 设置Response.StatusCode
为相应的代码(400、404、500)并返回响应时,错误页面控制器不会被调用。但是,如果我从控制器手动返回 a ,则会BadRequest();
调用错误页面控制器。
甚至可以从错误处理程序中间件类触发错误页面吗?如果是这样,我怎样才能实现这种行为?
这是我的错误处理中间件类。
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate nextDelegate;
public ErrorHandlingMiddleware(RequestDelegate nextDelegate)
{
this.nextDelegate = nextDelegate;
}
public async Task Invoke(HttpContext context, IOptions<MvcJsonOptions> options)
{
try
{
await this.nextDelegate(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex, options);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex, IOptions<MvcJsonOptions> options)
{
var httpStatusCode = HttpStatusCode.InternalServerError;
if (ex is CommonApiException commonApiException)
{
httpStatusCode = (HttpStatusCode)commonApiException.StatusCode;
}
var result = JsonConvert.SerializeObject(new { error = ex.Message }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)httpStatusCode;
return context.Response.WriteAsync(result);
}
}
我的启动配置
public void Configure(
IApplicationBuilder app,
IHostingEnvironment environment,
ILogger<Startup> logger,
ILoggerFactory factory)
{
app.UseExceptionHandler("/Error");
app.UseStatusCodePagesWithReExecute("/Error/StatusCode/{0}");
// ....
// ....
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();
}
错误页面控制器
public class ErrorController : Controller
{
[AllowAnonymous]
[Route("Error")]
[Route("Error/Index")]
[Route("Error/500")]
[SkipFilters("Bypass claims.")]
public IActionResult Index()
{
return this.View();
}
[AllowAnonymous]
[SkipFilters("Bypass claims.")]
[Route("Error/StatusCode/{code}")]
public IActionResult ErrorStatusCode(int code)
{
var statusCodeModel = new StatusCodeModel
{
ErrorStatusCode = code.ToString(),
OperationId = Activity.Current.RootId
};
var statusCodeReExecuteFeature = this.HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
statusCodeModel.OriginalUrl =
statusCodeReExecuteFeature.OriginalPathBase
+ statusCodeReExecuteFeature.OriginalPath
+ statusCodeReExecuteFeature.OriginalQueryString;
}
return this.View("StatusCode", statusCodeModel);
}
}
我用于测试的控制器
public class DummyController : Controller
{
[Route("Dummy")]
public IActionResult Dummy()
{
throw new CommonApiException("Test Error");
//return this.BadRequest(); //This triggers the error page controller.
}
}
解决方案
甚至可以从错误处理程序中间件类触发错误页面吗?如果是这样,我怎样才能实现这种行为?
是的。尝试修改您HandleExceptionAsync
ErrorHandlingMiddleware
的网址以重写您的网址:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate nextDelegate;
public ErrorHandlingMiddleware(RequestDelegate nextDelegate)
{
this.nextDelegate = nextDelegate;
}
public async Task Invoke(HttpContext context, IOptions<MvcJsonOptions> options)
{
try
{
await this.nextDelegate(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex, options);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception ex, IOptions<MvcJsonOptions> options)
{
var httpStatusCode = HttpStatusCode.InternalServerError;
PathString originalPath = context.Request.Path;
context.Request.Path = "/Error/StatusCode" + (int)httpStatusCode;
try
{
var exceptionHandlerFeature = new ExceptionHandlerFeature()
{
Error = ex,
Path = originalPath.Value,
};
context.Features.Set<IExceptionHandlerFeature>(exceptionHandlerFeature);
context.Features.Set<IExceptionHandlerPathFeature>(exceptionHandlerFeature);
context.Response.StatusCode = (int)httpStatusCode;
await this.nextDelegate(context);
return;
}
catch (Exception ex2)
{
}
finally
{
context.Request.Path = originalPath;
}
}
}
推荐阅读
- vue.js - 根据循环中的项目数量在课后显示
- microservices - 我应该在什么级别检查微服务中的记录存在?
- intellij-idea - Intellij:未找到模块 mysql.connector.java - git checkout 后出错
- sql - 需要可行的解决方案来解决我的无效条件创建
- node.js - 属性“chatServices”没有初始值设定项,也没有在构造函数中明确分配
- dataframe - 使用 Python 从数据框列中的列表中获取相同的值
- mysql - 更新具有 5 列的表中的 1 行,如果未更改,则使其他列具有旧值
- javascript - jQuery QueryBuilder:如何初始化它并设置只读参数
- python - 多语言错误:输入在字节 333789(361147)周围包含无效的 UTF-8
- python - 如何查询 csv 文件并更新值