Asp.net 结合了 Razor 页面和 ApiController 的应用程序中的核心异常处理

Asp.net core exception handling in applications that combines Razor Pages and ApiControllers

使用结合了 Razor Pages 和 Api 控制器的 asp.net 应用程序时。 如何全局检查 Api 控制器是否抛出异常?

想法是使用 UseExceptionHandler 中间件,但有条件地 return 如果从 Razor 页面和 json ProblemDetails 如果异常是从 ApiController

抛出的响应

对于 web Api,添加带有 Api 的属性路由,然后在中间件或异常处理程序中检查请求路径,如下所示:

app.UseExceptionHandler("/Error"); //handle the exception from the razor page

//handle the exception from the API.
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), subApp =>
{
    subApp.UseExceptionHandler(builder =>
    {
        builder.Run(async context =>
        {
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; 
            context.Response.ContentType = "application/json"; 
            await context.Response.WriteAsync("{\"error\":\"Exception from API!\"}");
            //await context.Response.WriteAsync("ERROR From API!<br><br>\r\n"); 
            //await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            //await context.Response.WriteAsync("</body></html>\r\n");
        });
    });
});

结果如下:

此外,您还可以使用自定义异常处理程序页面,为UseExceptionHandler 提供一个lambda。使用 lambda 允许在返回响应之前访问出错的请求路径。

例如:

//app.UseExceptionHandler("/Home/Error");
app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    { 
        var exceptionHandlerPathFeature =
            context.Features.Get<IExceptionHandlerPathFeature>();
        //check if the handler path contains api or not.
        if (exceptionHandlerPathFeature.Path.Contains("api"))
        { 
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; ;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("ERROR From API!<br><br>\r\n");

            await context.Response.WriteAsync(
                                            "<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n"); 
        }
        else
        {
            context.Response.Redirect("/Home/Error");
        }
    });
});

更多详细信息,请参阅