.Net Core MVC 中使用 Hellang 中间件进行异常处理

Ani*_*h V 5 middleware exception asp.net-core-mvc

我使用Hellang Middleware 进行异常处理,作为我的 MVC 应用程序中的全局异常处理机制。我在 Startup.cs 的 ConfigureServices 方法中添加了以下代码:

services.AddProblemDetails(opts =>
            {
                // Control when an exception is included
                opts.IncludeExceptionDetails = (ctx, ex) =>
                {
                    // Fetch services from HttpContext.RequestServices
                    var env = ctx.RequestServices.GetRequiredService<IHostEnvironment>();
                    return env.IsDevelopment() || env.IsStaging();
                };
                opts.ShouldLogUnhandledException = (ctx, e, d) =>
                {
                    return (d.Status.HasValue && d.Status.Value >= 500);
                };
            });
Run Code Online (Sandbox Code Playgroud)

我还添加了UseProblemDetails()配置方法。

然而我开始知道,如果我使用UseProblemDetails(),那就UseExceptionHandler()行不通了!因此,我无法找出将用户导航到常见错误视图页面的方法。

有没有什么方法可以将用户重定向到错误页面,同时坚持使用 Hellang Middleware 进行异常处理和日志记录?

Reb*_*cca 5

我有类似的问题。我像下面这样解决了它。在此示例中记录自定义业务故障异常:

services.AddProblemDetails(setup =>
{
    setup.Map<FaultException<BusinessFault>>((context, exception) =>
    {
        // resolve logger
        var logger = context.RequestServices.GetRequiredService<ILogger<ProblemDetails>>();

        // log exception to Seq
        logger.LogError(exception, "{@Exception} occurred.", exception);

        // return the problem details map   
        return new ProblemDetails
        {
            Title = exception.Message,
            Detail = exception.Detail.FaultMessage,
            Status = exception.Detail.FaultType.ToHttpStatus(),
            Type = exception.Detail.FaultType.ToString(),
            Instance = exception.Detail.FaultReference
        };
    });
});
Run Code Online (Sandbox Code Playgroud)


Ram*_* A. 4

请参阅此处的答案: https ://stackoverflow.com/a/40153711/90287

您必须区分请求的类型,是 API 请求还是 UI 请求,以确定是否应返回问题+详细信息 JSON 或是否应返回网页。

Configure这就是我在方法顶部附近所做的Startup.cs

app.UseWhen(context => context.IsApiRequest(), branch =>
{
    branch.UseProblemDetails();
});

app.UseWhen(context => !context.IsApiRequest(), branch =>
{
    branch.UseExceptionHandler("/Home/Error");
});
Run Code Online (Sandbox Code Playgroud)

您可以定义自己的自定义 HttpContext 扩展方法:

public static class HttpContextExtensions
{
    public static bool IsApiRequest(this HttpContext context)
    {
        return context.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase)
            || (context.Request.Headers["X-Requested-With"] == "XMLHttpRequest"); // AJAX request
    }
}
Run Code Online (Sandbox Code Playgroud)