代码之家  ›  专栏  ›  技术社区  ›  MeTitus

捕获中的异常ASP.NET核心MVC

  •  1
  • MeTitus  · 技术社区  · 6 年前

    我补充说:

    public abstract class GenericActionFilter : ActionFilterAttribute
    {
        protected readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    
    
        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (await OnBeforeActionExecutionAsync(context))
            {
                var executed = await next();
    
                if (executed.Exception != null && !executed.ExceptionHandled)
                {
                    await OnExceptionAsync(context, executed.Exception);
                }
                else
                {
                    await OnAfterActionExecutionAsync(context);
                }
            }
        }
    
        public virtual Task<bool> OnBeforeActionExecutionAsync(ActionExecutingContext context)
        {
            return Task.FromResult(true);
        }
    
        public virtual Task OnAfterActionExecutionAsync(ActionExecutingContext context)
        {
            return Task.CompletedTask;
        }
    
        public virtual Task OnExceptionAsync(ActionExecutingContext context, Exception ex)
        {
            return Task.CompletedTask;
        }
    }
    

    像这样使用:

    public class ExceptionFilter : GenericActionFilter
    {
        public IntegrationScenarioSettings Settings { get; set; }
    
    
        public override Task OnExceptionAsync(ActionExecutingContext context, Exception ex)
        {
            context.Result = new ContentResult
            {
                Content = Settings.ApiExecutionExceptionMessage,
                StatusCode = (int)HttpStatusCode.ServiceUnavailable
            };
    
            //outputs to endpoint.log
            Logger.Error(ex);
    
            return Task.CompletedTask;
        }
    }
    

    我在这里错过了什么?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Kirk Larkin    6 年前

    为了通知ASP.NET处理异常的核心MVC管道,需要设置 ActionExecutedContext.ExceptionHandled true . 因为在你展示的代码中没有这个ASP.NET核心MVC管道使用它自己的错误处理逻辑将(它认为是)未处理的异常转换为500响应。

    ActionExecutedContext 而不是开着 ActionExecutingContext (在代码中使用)。这是有道理的,因为 操作执行上下文 代表国家 之后 动作开始。这意味着您将需要以下一组更改:

    1. 更新您的 OnExceptionAsync 要执行的函数 ActionExecutedContext操作 操作执行上下文 .
    2. 将呼叫更新为 OneExceptionAsync executed context . 在这里,您还可以将方法参数折叠为 只是 执行 (我将在下面的代码中显示这一点)。
    3. context.ExceptionHandled 是的

    public abstract class GenericActionFilter : ActionFilterAttribute
    {
        public override async Task OnActionExecutionAsync(ActionExecutingContext context,
            ActionExecutionDelegate next)
        {
            if (await OnBeforeActionExecutionAsync(context))
            {
                var executed = await next();
    
                if (executed.Exception != null && !executed.ExceptionHandled)
                {
                    await OnExceptionAsync(executed); // #2.
                }
                else
                {
                    // NOTE: You might want to use executed here too.
                    await OnAfterActionExecutionAsync(context);
                }
            }
        }
    
        // ...
    
        public virtual Task OnExceptionAsync(ActionExecutedContext context) // #1.
        {
            return Task.CompletedTask;
        }
    }
    

    public class ExceptionFilter : GenericActionFilter
    {    
        public override Task OnExceptionAsync(ActionExecutedContext context) // #1, #2.
        {
            Logger.Error(context.Exception); // #2 (single parameter).
    
            context.Result = new ContentResult { ... };
            context.ExceptionHandled = true; // #3.
    
            return Task.CompletedTask;
        }
    }