.net core 異常過濾器的使用
第一種使用方式(全局注冊)
第二種方式(TypeFilter)
第三種方式(ServiceFilter)
第四種方式(IFilterFactory)
CustomExceptionFilterAttribute.cs
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute { private readonly ILogger<CustomExceptionFilterAttribute> _logger; private readonly IModelMetadataProvider _modelMetadataProvider; public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger, IModelMetadataProvider modelMetadataProvider) { _logger = logger; _modelMetadataProvider = modelMetadataProvider; } /// <summary> /// 發生異常時 進入 /// </summary> /// <param name="context"></param> public override void OnException(ExceptionContext context) { this._logger.LogError($"在響應 {context.HttpContext.Request.Path} 時出現異常,信息:{context.Exception.Message}"); if (!context.ExceptionHandled) //異常未被處理 { if (this.IsAjaxRequest(context.HttpContext.Request))//ajax請求 { context.Result = new JsonResult(new { Result = false, Msg = "發生錯誤,請聯系管理員", DebugMessage = context.Exception.Message });//中斷式---請求到這里結束了,不再繼續Action } else { var result = new ViewResult { ViewName = "~/Views/Shared/Error.cshtml" }; result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState); result.ViewData.Add("Exception", context.Exception.Message); context.Result = result; } context.ExceptionHandled = true;//異常已被處理 } } private bool IsAjaxRequest(HttpRequest request) { string header = request.Headers["X-Requested-With"]; return "XMLHttpRequest".Equals(header); } }
Error.cshtml
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width" /> <title>錯誤</title> </head> <body> <hgroup> <h1>錯誤。</h1> <h2>處理你的請求時出錯。</h2> <h3>異常信息:@ViewData["Exception"]</h3> @{ Console.WriteLine(ViewData["Exception"]); } </hgroup> </body> </html>
Ajax請求:
@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <button id="b01" type="button">Change Content</button> </div> @section scripts{ <script> $("#b01").click(function () { $.ajax({ url: 'http://localhost:5177/Custom',//地址 dataType: 'json',//數據類型 type: 'Post',//類型 timeout: 2000,//超時 //請求成功 success: function (data, status) { console.log(data.result); console.log(data.msg); console.log(data.debugMessage); } }); }); </script> }
第一種使用方式(全局注冊):
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(options => { options.Filters.Add(typeof(CustomExceptionFilterAttribute)); //全局注冊異常 }); services.AddControllersWithViews(); }
第二種方式(TypeFilter):
[TypeFilter(typeof(CustomExceptionFilterAttribute))] public class CustomController : Controller { public IActionResult Index() { Console.WriteLine("Custom/Index"); int i = 0; int k = 10; int j = k / i; //這里會異常 return View(); } }
第三種方式(ServiceFilter):
[ServiceFilter(typeof(CustomExceptionFilterAttribute))] public class CustomController : Controller { public IActionResult Index() { Console.WriteLine("Custom/Index"); int i = 0; int k = 10; int j = k / i; //這里會異常 return View(); } } public void ConfigureServices(IServiceCollection services) { services.AddTransient<CustomExceptionFilterAttribute>(); //注冊 services.AddControllersWithViews(); }
第四種方式(IFilterFactory)
public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory { Type _FilterType = null; public CustomIOCFilterFactoryAttribute(Type FilterType) { _FilterType = FilterType; } public bool IsReusable => true; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { return (IFilterMetadata)serviceProvider.GetService(this._FilterType); } } [CustomIOCFilterFactoryAttribute(typeof(CustomExceptionFilterAttribute))] public class CustomController : Controller { public IActionResult Index() { Console.WriteLine("Custom/Index"); int i = 0; int k = 10; int j = k / i; //這里會異常 return View(); } } public void ConfigureServices(IServiceCollection services) { services.AddTransient<CustomExceptionFilterAttribute>(); //注冊 services.AddControllersWithViews(); }