WebApi捕捉异常的一套方案

public class ExceptionFilter:ExceptionFilterAttribute
    {
        NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            actionExecutedContext?.Request?.Content?.ReadAsStreamAsync().Result.Seek(0, System.IO.SeekOrigin.Begin);
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"请求路径:{actionExecutedContext?.Request?.RequestUri}" );
            sb.AppendLine($"请求方法:{actionExecutedContext?.Request?.Method}" );
            sb.AppendLine($"请求正文:{actionExecutedContext?.Request?.Content?.ReadAsStringAsync().Result}" );
            //错误日志
            var ex = actionExecutedContext.Exception;
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
            }
            sb.AppendLine($"异常类型:{ex.GetType().Name}");
            sb.AppendLine($"异常说明:{ex.Message}");
            sb.AppendLine($"异常堆栈:{ex.StackTrace}");
            logger.Error(sb.ToString());
        }
    }

  简单说明一下上面的代码:

  继承ExceptionFilterAttribute类,并重写OnException方法。

  因为要获取请求中的正文,正文已经被之前的管道读取过,所以要把流的位置定位到最开始:actionExecutedContext?.Request?.Content?.ReadAsStreamAsync().Result.Seek(0, System.IO.SeekOrigin.Begin);

  

sb.AppendLine($"请求路径:{actionExecutedContext?.Request?.RequestUri}" );
sb.AppendLine($"请求方法:{actionExecutedContext?.Request?.Method}" );
sb.AppendLine($"请求正文:{actionExecutedContext?.Request?.Content?.ReadAsStringAsync().Result}" );

  这三段就是简单的把请求的url,Method,Content记录下来以便我们程序异常后根据日志重现问题。

var ex = actionExecutedContext.Exception;
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

  获取到最里面的Exception,将错误信息记录下来。这样就能获得比较全面的错误日志了。

  最后,要将我们的ExceptionFilter类替换掉api默认的Exception实现,找到WebApiConfig类,在HttpConfiguration的Filters中添加ExceptionFilter,代码如下:

  

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //跨域配置
            config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Filters.Add(new ExceptionFilter());
        }
    }

  大功告成!

  

  

猜你喜欢

转载自www.cnblogs.com/niye/p/9198301.html