asp.net core app.UseExceptionHandler() 来处理某些端点的异常?

asp.net core app.UseExceptionHandler() to handle exceptions for certain endpoints?

我正在向现有 ASP.NET 核心网络应用添加一些网络 API 方法。这意味着我的新网络 API 控制器将具有属性 [ApiController] 并且调用客户端将期望 return 输出为 JSON 而不是常规 HTML .

在另一个项目中,我使用 app.UseExceptionHandler(...) 实现了自定义异常处理程序,它在 JSON 中对响应进行编码,提供有关异常的信息。在这一个中,我想这样做,但只有当异常来自 [ApiController] 控制器内的操作方法时;否则我仍然想使用 app.UseExceptionHandler("/Home/Error");,因为异常来自常规页面并且响应应该是 HTML.

有没有一种方法可以设置异常处理程序,以便它知道异常来自何处,并相应地呈现响应?

请问您使用的是哪个版本ASP.Net Core? link 可能对您有所帮助。 ASP.Net Core Web Api

的异常处理程序中间件
var exceptionHandlerPathFeature =
        HttpContext.Features.Get<IExceptionHandlerPathFeature>();
     var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
     var detail = context.Error.StackTrace;
     var message = context.Error.Message;
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "File error thrown";
            _logger.LogError(ExceptionMessage);
        }
        if (exceptionHandlerPathFeature?.Path == "/index")
        {
            ExceptionMessage += " from home page";
        }

In this one, I want to do that, but only when the exception came from an action method inside an [ApiController] controller; otherwise I still want to use app.UseExceptionHandler("/Home/Error");, as the exception came from a regular page and the response should be HTML.

从你的描述来看,你似乎想检测异常来自哪里,如果异常来自API方法,你将使用带有自定义响应的自定义异常处理程序,否则它将通过 Home/Error 页面显示错误消息。

在这种情况下,自定义异常处理程序页面的替代方法是为 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");
        }
    });
});

结果如下:

更多详细信息,请参阅Exception handler lambda and

在 ASP.Net Core 6 中,您可以从 IExceptionHandlerFeature 中获取 Endpoint,直到那时您可以在路由中间件之后自己捕获 Endpoint 并将其存储在功能并在异常处理程序代码中使用它。

app.UseExceptionHandler("/Error");
app.UseRouting();
app.Use(async (context, next) =>
{
    var feature = new EndpointFeature
    {
        Endpoint = context.GetEndpoint()
    };
    context.Features.Set(feature);
    await next();
});
app.UseEndpoints(endpoints =>
{
    endpoints.Map("/Error", context =>
    {
        var feature = context.Features.Get<EndpointFeature>();
        var endpointMetadata = feature.Endpoint.Metadata;
    });
});