如何解决异常中间件中的 URL 重写
我正在尝试进行一些自定义异常处理,在那里我需要重定向。
他们走的路应该是这样
app.UseExceptionHandler(appBuilder =>
{
appBuilder.Use(async (ctx,next) =>
{
ctx.Request.Path = "/Error";
await next();
});
});
但什么也没发生,只有一个空白的 500 页。
除了使用的任何想法
ctx.Response.Redirect("/Error")
解决方法
当你使用UseExceptionHandler
的重载接受一个Action<IApplicationBuilder>
时,你需要为里面的子构建器配置一个完整的管道,以便在异常分支上重新执行管道。在您的代码中,您只需设置 Request.Path
,但它不会被任何代码处理。最后需要添加一个MVC中间件作为终端。您可以像配置主管道 (UseMvc
,UseEndpoints
) 一样对其进行配置。在这种情况下,终端只需要使用您之前设置的特定请求路径即可。代码如下:
app.UseExceptionHandler(appBuilder => {
appBuilder.Use(async (ctx,next) => {
ctx.Request.Path = "/Error";
await next();
});
//add the terminal to handle the branched request
appBuilder.UseMvc();
});
现在,当您遇到一些未处理的异常时,它应该像 app.UseExceptionHandler("/Error")
一样工作。
根据您的描述,我建议您可以先尝试了解异常处理程序的工作原理。
根据source codes,你可以找到如果你想编写自定义中间件,你应该像这样使用第二个函数:
public static IApplicationBuilder UseExceptionHandler(this IApplicationBuilder app,Action<IApplicationBuilder> configure)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
var subAppBuilder = app.New();
configure(subAppBuilder);
var exceptionHandlerPipeline = subAppBuilder.Build();
return app.UseExceptionHandler(new ExceptionHandlerOptions
{
ExceptionHandler = exceptionHandlerPipeline
});
}
如果你使用这个函数,你会发现它仍然会调用 ExceptionHandlerMiddleware 及其新的 exceptionHandlerPipeline。在 ExceptionHandlerMiddleware 中,您会发现它会调用此请求 delaget。
所以如果你不捕获异常并直接设置上下文路径,它将不起作用。所以我建议你可以尝试使用以下代码:
app.UseExceptionHandler(appBuilder =>
{
app.Use(async (context,next) =>
{
try
{
await next();
}
catch (Exception ex)
{
ClearHttpContext(context);
var exceptionHandlerFeature = new ExceptionHandlerFeature()
{
Error = ex,Path = "/Home/Index",};
context.Request.Path = "/Home/Error";
context.Features.Set<IExceptionHandlerFeature>(exceptionHandlerFeature);
context.Features.Set<IExceptionHandlerPathFeature>(exceptionHandlerFeature);
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.OnStarting(ClearCacheHeaders,context.Response);
await next();
}
});
});
ClearCacheHeaders 方法:
private static Task ClearCacheHeaders(object state)
{
var headers = ((HttpResponse)state).Headers;
headers[HeaderNames.CacheControl] = "no-cache,no-store";
headers[HeaderNames.Pragma] = "no-cache";
headers[HeaderNames.Expires] = "-1";
headers.Remove(HeaderNames.ETag);
return Task.CompletedTask;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。