【问题标题】:How to show custom page for 400 error in .net core 3.0如何在 .net core 3.0 中显示 400 错误的自定义页面
【发布时间】:2020-02-22 01:56:51
【问题描述】:

我的错误处理设置如下:

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 的方法对此进行了测试,它可以工作,我得到了我的错误页面。实际上,在大多数情况下,当我对此进行测试时,我得到了错误页面。但是有一种情况我没有得到那个页面。

如果您创建了一个发布操作(实际上是任何操作)并需要一个防伪令牌。现在,如果您向该方法提交表单,但在您的 html 中删除自动生成的防伪令牌,服务器会以 400 状态响应,并且不使用我的错误页面。我得到的页面是浏览器默认的页面,如果你不提供的话。

附加说明:我的异常处理程序甚至没有捕捉到这个错误。处理程序构造函数看起来像这样:

public async Task Invoke(HttpContext context)
{
    try
    {
        await _requestDelegate.Invoke(context);
    }
    catch (Exception exception)
    {
        HandleExceptionAsync(context, exception);
    }
}

为什么会这样?当涉及到错误处理时,我该如何考虑所有情况?

【问题讨论】:

  • 您发现了一个错误。我一直在研究这个,发现问题是因为 rexecute 回到了同一个端点。这是因为要使用的端点已经被选中,并且没有被清除以重新执行。
  • 建议的解决方法如下:github.com/aspnet/AspNetCore/issues/…
  • @KirkLarkin 我尝试了解决方法,但这并没有改变我的任何事情。我仍然收到 400 响应,并且页面上的内容显示:“此页面无法正常工作”,看起来像是由浏览器生成的,它没有加载我的实际错误页面。

标签: c# asp.net-core error-handling .net-core asp.net-core-3.0


【解决方案1】:

这实际上是两个问题。第一个问题是一个错误,可以在这里找到解决方法:

https://github.com/aspnet/AspNetCore/issues/13715#issuecomment-528929683

第二个问题是因为我对防伪令牌进行了自动验证。这意味着当页面重新执行时,它又是一个帖子,因此防伪再次失败,因此无法访问我的错误页面。所以解决方案是在错误控制器上添加 IgnoreAntiforgeryToken 属性。

【讨论】:

    【解决方案2】:

    当防伪验证失败时,服务器 (ASP.Net Core) 返回错误 404 并停止对请求的进一步处理,并且您的任何异常处理程序都不会捕获该错误。你可以做的是使用UseStatusCodePagesWithRedirects,如下所示

    app.UseStatusCodePagesWithReExecute("/Error"); // "/Error" is your custom error handling page.
    

    然后对错误做任何你喜欢做的事情。

    使用UseStatusCodePagesWithReExecute 处理错误的完整示例应用程序here

    【讨论】:

    • 但在我上面的示例中,我已经在使用 UseStatusCodePagesWithReExecute 并且它具有我所描述的行为。我是不是有些不明白?
    • 是的,如果您转到 here。在OnGet 中,您可以基于ErrorStatusCode 或其他内容重定向到另一个页面(您的自定义错误页面)。
    • StatusCodeModel 是您链接到的类。我认为我必须为此创建一个才能正常工作。但是如何在启动时注册我的课程?
    • StatusCodeModel 是一个页面。 ASP.Net Core 具有页面和带有控制器的传统视图。你不需要注册任何东西。只需将 URL 路径传递给页面或视图。
    • 对不起,我想我现在更加迷茫你试图向我解释什么。我想我需要从头开始,以帮助我们双方达成一致。我已经在我的启动代码中调用app.UseStatusCodePagesWithReExecute("/Error"); 但是,当我收到防伪令牌错误时,它不会将我重定向到该网址。所以我用来处理错误的错误页面不会触发。那么如何在我的代码中让 .net core 将用户重定向到我已经存在的通用错误页面?
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多