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

