如何在 .net core 3.0 中显示 400 错误的自定义页面
How to show custom page for 400 error in .net core 3.0
我的错误处理设置如下:
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ExceptionHandlerMiddleware>();
app.UseStatusCodePagesWithReExecute("/Error/Index");
//I Added this as a test but it had no effect.
app.Use((context, next) => {
context.SetEndpoint(null);
return next();
});
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = (context) =>
{
context.Context.Response.GetTypedHeaders()
.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromDays(30)
};
}
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
现在我通过尝试 localhost/mynotexistantpage 之类的方法对此进行了测试并且它有效,我得到了我的错误页面。实际上,在大多数情况下,当我测试这个时,我得到了错误页面。但是有一种情况我没有得到那个页面。
如果您创建了一个 post 动作(实际上是任何动作)并且需要一个防伪令牌。现在,如果您向该方法提交表单,但在 html 中删除自动生成的防伪令牌,服务器将以 400 状态响应,并且不会使用我的错误页面。如果您不提供,我得到的页面是浏览器默认的页面。
附加说明:我的异常处理程序甚至没有捕获到此错误。处理程序构造函数看起来像这样:
public async Task Invoke(HttpContext context)
{
try
{
await _requestDelegate.Invoke(context);
}
catch (Exception exception)
{
HandleExceptionAsync(context, exception);
}
}
为什么会这样?当涉及到错误处理时,我该如何考虑所有情况?
当防伪验证失败时服务器(ASP.Net 核心)returns 错误 404 并停止进一步处理请求,none 的异常处理程序将捕获该错误。你可以做的是像下面那样使用 UseStatusCodePagesWithRedirects
app.UseStatusCodePagesWithReExecute("/Error"); // "/Error" is your custom error handling page.
然后随心所欲地处理错误。
使用 UseStatusCodePagesWithReExecute
.
进行错误处理的完整示例应用程序 here
这实际上是 2 个问题。第一个问题是错误,可以在此处找到解决方法:
https://github.com/aspnet/AspNetCore/issues/13715#issuecomment-528929683
第二个问题是因为我对防伪令牌进行了自动验证。这意味着当页面重新执行时,它又是一个 post,因此防伪再次失败,因此无法到达我的错误页面。因此解决方案是在错误控制器上添加 IgnoreAntiforgeryToken 属性。
我的错误处理设置如下:
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ExceptionHandlerMiddleware>();
app.UseStatusCodePagesWithReExecute("/Error/Index");
//I Added this as a test but it had no effect.
app.Use((context, next) => {
context.SetEndpoint(null);
return next();
});
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = (context) =>
{
context.Context.Response.GetTypedHeaders()
.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromDays(30)
};
}
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
现在我通过尝试 localhost/mynotexistantpage 之类的方法对此进行了测试并且它有效,我得到了我的错误页面。实际上,在大多数情况下,当我测试这个时,我得到了错误页面。但是有一种情况我没有得到那个页面。
如果您创建了一个 post 动作(实际上是任何动作)并且需要一个防伪令牌。现在,如果您向该方法提交表单,但在 html 中删除自动生成的防伪令牌,服务器将以 400 状态响应,并且不会使用我的错误页面。如果您不提供,我得到的页面是浏览器默认的页面。
附加说明:我的异常处理程序甚至没有捕获到此错误。处理程序构造函数看起来像这样:
public async Task Invoke(HttpContext context)
{
try
{
await _requestDelegate.Invoke(context);
}
catch (Exception exception)
{
HandleExceptionAsync(context, exception);
}
}
为什么会这样?当涉及到错误处理时,我该如何考虑所有情况?
当防伪验证失败时服务器(ASP.Net 核心)returns 错误 404 并停止进一步处理请求,none 的异常处理程序将捕获该错误。你可以做的是像下面那样使用 UseStatusCodePagesWithRedirects
app.UseStatusCodePagesWithReExecute("/Error"); // "/Error" is your custom error handling page.
然后随心所欲地处理错误。
使用 UseStatusCodePagesWithReExecute
.
这实际上是 2 个问题。第一个问题是错误,可以在此处找到解决方法:
https://github.com/aspnet/AspNetCore/issues/13715#issuecomment-528929683
第二个问题是因为我对防伪令牌进行了自动验证。这意味着当页面重新执行时,它又是一个 post,因此防伪再次失败,因此无法到达我的错误页面。因此解决方案是在错误控制器上添加 IgnoreAntiforgeryToken 属性。