如何在 ASP.NET Core 中以不同方式处理(或区分)API 调用和 MVC(视图)调用的错误 [英] How to handle errors differently for (or distinguish between) API calls and MVC (views) calls in ASP.NET Core

查看:9
本文介绍了如何在 ASP.NET Core 中以不同方式处理(或区分)API 调用和 MVC(视图)调用的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

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

解决方案

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

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

实施:

//用于api公共类 ApiExceptionFilterAttribute : ExceptionFilterAttribute{公共覆盖无效 OnException(ExceptionContext 上下文){//以 json 格式发送错误}}[ApiExceptionFilter]公共类 ApiController : 控制器{...}//对于mvc公共类 MvcExceptionFilterAttribute : ExceptionFilterAttribute{公共覆盖无效 OnException(ExceptionContext 上下文){//发送视图结果}}[MvcExceptionFilter]公共类 HomeController : Controller{...}

如果要全局添加过滤器,请参阅注册区域过滤器

2- 使用 UseWhenUseExceptionHandler

 app.UseWhen(x => x.Request.Path.Value.StartsWith("/api"), builder =>{builder.UseExceptionHandler(新的 ExceptionHandlerOptions(){ExceptionHandler = async (ctx) =>{var feature = ctx.Features.Get();var error = feature?.Error;//发送 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();var error = feature?.Error;//发送 json}别的{//重定向错误页面}}});

In my applications based on ordinary MVC and WebApi I had two different error handling routes.

If an error occurred during WebApi call, I would intercept it (using standard web api options) and return json message with corresponding HTTP Status Code so that client app can handle it.

If the error happened in MVC, then I would use some standard handlers that would redirect user to some default error screen possibly based on status code.

Now in ASP.NET Core both are joined in the same framework, so if I just intercept and return JSON, then I risk showing json to a user, since it can be an action that returns a view. On the other hand if I use app.UseExceptionHandler then my API calls would get HTML from the error page that is unusable inside js.

What is the good way to provide separate error handling for this two cases? Or perhaps there is a better way to handle it altogether?

P.S. I would rather reuse the MVC exception handler that comes out of the box and only add the web api part.

解决方案

There are many ways to achive your goal:

1- Using two different exception filter(i would go with this approach because your question is about mvc pipline)

Implementation:

// 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{...}

If you want to add filter globally, see Register filter for an area

2- Using UseWhen and UseExceptionHandler

         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- Using UseExceptionHandler conditionally:

        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
                }
            }
        });

这篇关于如何在 ASP.NET Core 中以不同方式处理(或区分)API 调用和 MVC(视图)调用的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆