Filter-Controller级别的捕捉异常
新建GlobalExceptionsFilter
新建类GlobalExceptionsFilter
继承自IAsyncExceptionFilter
也可以集成同步的接口ExceptionFilter
建议用异步的。
/// <summary>
/// 只能管到Controller 之外的异常无法捕获
/// </summary>
public class GlobalExceptionsFilter : IAsyncExceptionFilter
{
private readonly ILogHelper _log;
public GlobalExceptionsFilter(ILogHelper log)
{
_log = log;//这就是之前做的日志方法
}
public Task OnExceptionAsync(ExceptionContext context)
{
if (context.ExceptionHandled == false)
{
Exception ex = context.Exception;
//这里给系统分配标识,监控异常肯定不止一个系统。
int sysId = 1;
//这里获取服务器ip时,需要考虑如果是使用nginx做了负载,这里要兼容负载后的ip,
//监控了ip方便定位到底是那台服务器出故障了
string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
var uri = context.HttpContext.Request.Path.Value;
_log.LogErr("Controller全局异常", $"系统编号:{sysId},主机IP:{ip}\r\r<br>异常Uri:{uri}\r\r<br>异常描述:{ex.Message}\r\r<br>堆栈信息:{ex.StackTrace}");
context.Result = new JsonResult(new CorePeoject.ViewModel.MessageModel<object>
{
Msg= "Controller全局异常拦截:" + ex.Message
});
}
context.ExceptionHandled = true; //异常已处理了
return Task.CompletedTask;
}
}
context.ExceptionHandled = true; //代表此异常已处理,无需后续拦截器处理
配置
API
Startup中ConfigureServices中增加配置
services.AddControllers(options =>
{
options.Filters.Add(typeof(Filter.GlobalExceptionsFilter));
});
MVC
Startup中ConfigureServices中增加配置
services.AddMvc(option =>
{
option.Filters.Add(typeof(GlobalExceptionFilter));
});
Middlerware级别异常捕捉
新建异常捕捉管道,在最外层进行捕捉,可以捕捉Controller以外的异常
新建GlobalExceptionMiddleware
/// <summary>
/// 全局异常拦截器 GlobalExceptionsFilter无法拦截的在此拦截
/// </summary>
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogHelper _log;
public GlobalExceptionMiddleware(RequestDelegate next, ILogHelper log)
{
_next = next;
_log = log;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception e)
{
int sysId = 1;//可以配置
string ip = context.Connection.RemoteIpAddress.ToString();
var uri = context.Request.Path.Value;
_log.LogErr("Middleware全局异常", $"系统编号:{sysId},主机IP:{ip}\r\r<br>异常Uri:{uri}\r\r<br>异常描述:{e.Message}\r\r<br>堆栈信息:\r\r<br>{e.StackTrace}");
var result = JsonHelper.SerializeObjectAsync((new CorePeoject.ViewModel.MessageModel<object>
{
Msg = "Middleware全局异常拦截:"+e.Message
}));
context.Response.ContentType = "application/json;charset=utf-8";
await context.Response.WriteAsync(await result);
}
}
配置中间件
Startup的Configure中配置
///全局异常拦截中间件 建议放在最外围
app.UseMiddleware<GlobalExceptionMiddleware>();
测试
在Controller中直接抛出 异常测试GlobalExceptionsFilter的捕捉 关闭Filter拦截 测试中间件捕捉
附录:Jsonhelper
public static class JsonHelper
{
//static JsonConvertHelp jsonConvertHelp = new JsonConvertHelp();
static private JsonSerializerSettings w = null;
static private JsonSerializerSettings r = null;
static private readonly object locker = new object();
static JsonHelper()
{
if (w == null || r == null)
{
lock (locker)
{
w = new JsonSerializerSettings();
w.ContractResolver = new CamelCasePropertyNamesContractResolver();
w.DateFormatString = "yyyy-MM-dd HH:mm:ss.fff";
//w.Converters.Add(jsonConvertHelp);
r = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
// s1.Converters.Add(jsonConvertHelp);
}
}
}
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <param name="isCamel">是否转换成驼峰式命名</param>
/// <returns>json字符串</returns>
public static Task<string> SerializeObjectAsync<T>(T o, bool isCamel = false) where T : class
{
if (o == null) return Task.FromResult("");
return isCamel ? Task.Run(() => JsonConvert.SerializeObject(o, w)) :
Task.Run(() => JsonConvert.SerializeObject(o));
// return json;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <param name="isCamel">是否转换成驼峰式命名</param>
/// <returns>对象实体</returns>
public static Task<T> DeserializeJsonToObjectAsync<T>(string json, bool isCamel = false) where T : class
{
return isCamel ?
Task.Run(() => JsonConvert.DeserializeObject<T>(json, r))
: Task.Run(() => JsonConvert.DeserializeObject<T>(json));
}
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <param name="isCamel">是否转换成驼峰式命名</param>
/// <returns>json字符串</returns>
public static string SerializeObject<T>(T o, bool isCamel = false) where T : class
{
if (o == null) return "";
return isCamel ? JsonConvert.SerializeObject(o, w) :
JsonConvert.SerializeObject(o);
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <param name="isCamel">是否转换成驼峰式命名</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json, bool isCamel = false) where T : class
{
return isCamel ?
JsonConvert.DeserializeObject<T>(json, r):
JsonConvert.DeserializeObject<T>(json);
}
}