【问题标题】:How to specify error handler for a specific API controller?如何为特定的 API 控制器指定错误处理程序?
【发布时间】:2021-02-06 03:01:15
【问题描述】:

我有一个 ASP.NET Core 应用程序,它具有 MVC 视图但也很少有 API,已经为应用程序定义了错误处理。 ErrorController 正在恢复 HTML 视图,我不想改变这种行为。但是,我正在引入新的 API 控制器,并且我想决定在抛出任何未处理的异常时返回什么 JSON(不是 HTML)。

我可以为给定的控制器指定错误处理程序,以便它返回我想要的 500 的 JSON 吗?

【问题讨论】:

    标签: api asp.net-core


    【解决方案1】:

    在 asp.net 核心中,作为cross-cutting concern 处理异常基本上有两种方法。一种是使用IExceptionFilterIAsyncExceptionFilter 用于异步处理),一种是使用异常处理程序中间件。异常过滤器无法处理所有异常,例如结果执行中发生的异常(序列化数据时,...)。所以使用异常处理器中间件处理异常是最可靠的。

    您可以自己找到有关异常过滤器的更多信息,只需使用属性装饰您的控制器类,它就可以非常容易地用于您的场景(针对特定控制器)。但是在这里我想介绍如何使用异常处理程序中间件来处理它,该中间件可以在Startup 类的Configure 方法中配置。这里我们使用IExceptionHandlerFeature 来获取异常信息(如果有的话):

     //exception handler for errors in other controllers & pages ...
     app.UseExceptionHandler("/Error");
     //exception handler for specific controllers
     app.MapWhen(context => {
                    var controller = context.GetRouteValue("controller")?.ToString();
                    return controller?.ToLower() == "your_controller_name";
                }, subApp => {
                    subApp.Run(async context =>
                    {
                        var exceptionHandlerFeature = context.Features.Get<IExceptionHandlerFeature>();
                        var exception = exceptionHandlerFeature?.Error;
                        if (exception != null)
                        {
                            //prepare the error by your own
                            var error = new { Messsage = exception.Message };
                            context.Response.ContentType = "application/json";
                            //set status code of your choice
                            //context.Response.StatusCode = ;
                            //write JSON response containing the error
                            await context.Response.WriteAsync(JsonSerializer.Serialize(error));
                        }
                    });
                });   
    

    请注意,我们使用MapWhen 将管道切换到终端中间件(由subApp 配置)。该终端中间件将拦截该请求,使其在处理流程中不被其他中间件进一步处理。您可以看到在其他情况下放置UseExceptionHandler 的顺序很重要。由于中间件是如何沿着请求处理管道构建的,它必须放在MapWhen 之前。

    您还可以将自己的自定义中间件创建到单独的类中(遵循基于约定或基于工厂的方法)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 2012-11-03
      • 2014-01-16
      • 2017-12-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      相关资源
      最近更新 更多