使用ExceptionFilter

  前面提到,过滤器可以处理错误异常。这里可以实践一把。

  新建一个.NET Core MVC控制器(.net core WebAPI也类似)。

  我在Test/Index Action方法中故意制造一个异常(我们知道在被除数不能为0).

public IActionResult Index()
{
     int a = 0, b = 5;
     var result = b/a;
}
using System.IO.Compression;

#pragma warning disable 414, 3021

namespace MyApplication
{
    [Obsolete("...")]
    class Program : IInterface
    {
        public static List<int> JustDoIt(int count)
        {
            Console.WriteLine($"Hello {Name}!");
            return new List<int>(new int[] { 1, 2, 3 })
        }
    }
}

  在Visual Studio中调试报错了
使用场景

  我们深知,异常这样报错很不友好,于是我们用了万能的try-catch

public IActionResult Index()
{
      try
        {
            int a = 0, b = 5;
            var result = b / a;
        } catch (Exception)
        {
            throw new ArgumentException("被除数不能为0", "a");
        }
}

  这样异常提示确实友好了,并且我们拦截了异常,甚至可以将异常记录到日志中。

使用场景

  但是每个方法都这样加会不会觉得很烦?有没有想过一劳永逸的办法。从架构层面应该这样思考。

  在传统的 Asp.Net MVC 应用程序中,我们一般都使用服务过滤的方式去捕获和处理异常,这种方式 非常常见,而且可用性来说,体验也不错,幸运的是 Asp.Net Core也完整的支持该方式。 新建一个全局异常过滤器GlobalExceptionFilter.cs,继承自IExceptionFilter。

public class GlobalExceptionFilter:Attribute, IExceptionFilter
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly IModelMetadataProvider _modelMetadataProvider;

        public GlobalExceptionFilter(
            IHostingEnvironment hostingEnvironment,
            IModelMetadataProvider modelMetadataProvider)
        {
            _hostingEnvironment = hostingEnvironment;
            _modelMetadataProvider = modelMetadataProvider;
        }
        /// <summary>
        /// 发生异常进入
        /// </summary>
        /// <param name="context"></param>
        public async void OnException(ExceptionContext context)
        {
            ContentResult result = new ContentResult
            {
                StatusCode = 500,
                ContentType = "text/json;charset=utf-8;"
            };

            if (_hostingEnvironment.IsDevelopment())
            {
                var json = new { message = context.Exception.Message };
                result.Content = JsonConvert.SerializeObject(json);
            }
            else
            {
                result.Content = "抱歉,出错了";
            }
            context.Result = result;
            context.ExceptionHandled = true;
        }
    }

  我们在startup.cs中进行中注入

// 将异常过滤器注入到容器中
services.AddScoped<GlobalExceptionFilter>();

  然后在需要的控制器上加上特性**ServiceFilter(typeof(GlobalExceptionFilter))]

 [ServiceFilter(typeof(GlobalExceptionFilter))]
 public class TestController : Controller

  启动程序,错误提示,页面只会显示单纯错误信息。

{“message”:“Attempted to divide by zero.”}

版权声明: 本文为智客工坊「楠木大叔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

results matching ""

    No results matching ""