.net Razor Pages中状态代码的自定义错误页面

hfsqlsce  于 2023-05-08  发布在  .NET
关注(0)|答案(2)|浏览(153)

bounty还有2天到期。回答此问题可获得+50声望奖励。Vincent希望引起更多关注这个问题。

以前,我能够让API服务器返回自定义API响应错误。我不得不覆盖.NET中的许多默认值来返回json,例如:使用UseMiddleware的全局异常中间件,使用UseStatusCodePages的处理程序构建状态代码json,配置ApiBehaviorOptions,以便模型绑定错误返回符合我需要的json格式。
我现在使用的是.NET 6 Razor Pages。我想返回异常/错误的自定义错误页面。我使用UseExceptionHandler来捕获管道中的异常,它可以工作。然而,当MultipartBodyLengthLimit上传的大小太大时,Configure<FormOptions>会产生错误,而Antiforgery错误不会使用我所理解的设计。像这样的错误抛出通用的400 Bad Request状态代码。我想返回一个自定义的响应页面,提供更多的错误信息。我不知道它在管道中的哪里抛出错误并处理它,因为根据文档,大文件上传应该抛出InvalidDataException https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.features.formoptions.multipartheaderslengthlimit?view=aspnetcore-6.0#microsoft-aspnetcore-http-features-formoptions-multipartheaderslengthlimit。但我在全局错误处理程序中间件和UseStatusCodePages内部尝试了try/catch块,两者都没有捕获InvalidDataException。我尝试在UseStatusCodePages内部解析context.HttpContext.Features.Get<IExceptionHandlerPathFeature>();,但结果是空的。我还尝试了AddMvcOptionsoptions.Filters.Add(new CustomExceptionFilter());,并尝试在OnPageHandlerExecutionAsync内部捕获。我在网上找过资源,但没有针对这种行为的。
我想捕捉框架抛出的错误,并给予错误消息,告诉原因,而不仅仅是400 Bad Request。如果有人对此有一些见解,我将非常感激。谢谢你

syqv5f0l

syqv5f0l1#

这里只是一个观察,因为我遇到了类似的问题,那是你的.net 6应用程序的.net 7资源的链接吗?还有,你的async模块什么时候执行?

2g32fytz

2g32fytz2#

我想我已经想好了... UseStatusCodePagesWithReExecute("/Error")UseExceptionHandler("/Error")都调用请求管道 * 两次 *。但仅更改.Path.QueryString
我相信在.UseEndpoint中间件执行请求过滤器时会触发防伪造错误。任何异常都将在EndpointMiddleware返回之前被捕获。
由于中间件管道执行两次,因此需要清除任何可能导致错误的状态。任何时候你看到你的错误页面没有被使用,这是由于错误条件仍然在HttpContext的状态。
那么我们能做些什么呢?在github上为每个发现的情况提出一个bug。但作为一种变通方法,您可能应该分叉一个更简单的管道,以便您可以更好地控制错误或状态页面的显示方式。

app.UseStatusCodePages(builder => {
    builder.Use(_next =>
    {
        var eds = app.ApplicationServices.GetRequiredService<EndpointDataSource>();

        // find the /Error razor page GET handler
        var endpoint = eds.Endpoints
            .OfType<RouteEndpoint>()
            .Where(e => e.RoutePattern.RawText == "Error")
            .Single();
        var endpointHandler = endpoint.RequestDelegate;

        return async context =>
        {
            // ensure we don't repeat any POST anti-forgery errors
            context.Request.Method = "GET";
            context.SetEndpoint(endpoint);
            await endpointHandler(context);
        };
    });
});

相关问题