c# - 如何在 ASP.NET Core 中以不同方式处理(或区分)API 调用和 MVC( View )调用的错误

标签 c# asp.net-core asp.net-web-api error-handling asp.net-core-mvc

在我基于普通 MVC 和 WebApi 的应用程序中,我有两种不同的错误处理路线。

如果在 WebApi 调用期间发生错误,我会拦截它(使用标准 Web api 选项)并返回带有相应 HTTP 状态代码的 json 消息,以便客户端应用程序可以处理它。

如果错误发生在 MVC 中,那么我将使用一些标准处理程序,这些处理程序可能会根据状态代码将用户重定向到某个默认错误屏幕。

现在在 ASP.NET Core 中,两者都加入了同一个框架,所以如果我只是拦截并返回 JSON,那么我就有可能向用户显示 json,因为它可能是一个返回 View 的操作。另一方面,如果我使用 app.UseExceptionHandler那么我的 API 调用将从错误页面中获取 HTML,该页面在 js 中无法使用。

为这两种情况提供单独的错误处理的好方法是什么?或者也许有更好的方法来完全处理它?

附言我宁愿重用开箱即用的 MVC 异常处理程序,只添加 web api 部分。

最佳答案

有很多方法可以实现您的目标:

1- 使用两个不同的异常过滤器 (我会采用这种方法,因为您的问题是关于 mvc pipline)

执行:

// For api
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // send error as json
    }
}


[ApiExceptionFilter]
public class ApiController : Controller{...}

// For mvc
public class MvcExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // send view result
    }
}


[MvcExceptionFilter]
public class HomeController : Controller{...}

如果要全局添加过滤器,请参阅 Register filter for an area

2- 使用 UseWhenUseExceptionHandler
         app.UseWhen(x => x.Request.Path.Value.StartsWith("/api"), builder =>
         {
             builder.UseExceptionHandler(new ExceptionHandlerOptions()
             {
                 ExceptionHandler = async (ctx) =>
                 {
                     var feature = ctx.Features.Get<IExceptionHandlerFeature>();
                     var error = feature?.Error;
                     // send json
                 }
             });
         });
        app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
        {
            builder.UseExceptionHandler("/Error");
        });`

3- 使用 UseExceptionHandler有条件:
        app.UseExceptionHandler(new ExceptionHandlerOptions()
        {
            ExceptionHandler = async (ctx) =>
            {
                if (ctx.Request.Path.Value.StartsWith("/api"))
                {
                    var feature = ctx.Features.Get<IExceptionHandlerFeature>();
                    var error = feature?.Error;
                    // send json
                }
                else
                {
                    // redirect error page
                }
            }
        });

关于c# - 如何在 ASP.NET Core 中以不同方式处理(或区分)API 调用和 MVC( View )调用的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40149061/

相关文章:

c# - 如何禁用 Windows Media Player 中的右键单击

c# - 访问 ASP.NET Web 用户控件的内部值

asp.net-core - 如何在 Entity Framework 核心2中使用自动迁移

c# - 从 View 组件中获取 session ID

azure - 如何在 Service Fabric 应用程序中添加 .NET Core 类库引用

c# - LINQ to Entities 仅支持无参数构造函数和初始值设定项。 (ASP.NET 网络 API)

c# - InvokeRequired 属性的值何时更改?

c# - Moq第一次和第二次返回不同的值

asp.net-core - ASP.NET Core 忽略 ASPNET_ENV 和托管 :Environment

c# - 无法从 apicontroller 中的 OwinContext 获取 UserManager