.net core简单引用abp vnext异常过滤
- abp在AbpAspNetCoreMvcModule里添加AbpExceptionFilter过滤器的,异常管理主要通过AbpExceptionFilter实现
public class AbpAspNetCoreMvcModule : AbpModule { //......省略若干代码 Configure<MvcOptions>(mvcOptions => { mvcOptions.AddAbp(context.Services); }); //...... }public static void AddAbp(this MvcOptions options, IServiceCollection services) { //... AddActionFilters(options); //... }private static void AddActionFilters(MvcOptions options) { // ... // 异常过滤器 options.Filters.AddService(typeof(AbpExceptionFilter)); } - AbpExceptionFilter过滤器在AbpAspNetCoreMvcModule里添加的,可以直接用,也可以自己添加过滤器重写AbpExceptionFilter自定义Exception类型与返回result
public class MyExceptionFilter : AbpExceptionFilter, ITransientDependency { public MyExceptionFilter(IExceptionToErrorInfoConverter errorInfoConverter, IHttpExceptionStatusCodeFinder statusCodeFinder, Volo.Abp.Json.IJsonSerializer jsonSerializer, IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions) : base(errorInfoConverter, statusCodeFinder, jsonSerializer, exceptionHandlingOptions) { } /// <summary> /// 是否需要进入异常处理 /// </summary> /// <param name="context"></param> /// <returns></returns> protected override bool ShouldHandleException(ExceptionContext context) { //TODO: Create DontWrap attribute to control wrapping..? if (context.ActionDescriptor.IsControllerAction() && context.ActionDescriptor.HasObjectResult()) { return true; } if (context.HttpContext.Request.CanAccept(MimeTypes.Application.Json)) { return true; } if (context.HttpContext.Request.IsAjax()) { return true; } return false; } /// <summary> /// 异常处理 /// </summary> /// <param name="context"></param> /// <returns></returns> protected override async Task HandleAndWrapException(ExceptionContext context) { //TODO: Trigger an AbpExceptionHandled event or something like that. //定义Headers context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); //定义状态码 可以新增Exception类型,重写IHttpExceptionStatusCodeFinder获取返回StatusCode context.HttpContext.Response.StatusCode = (int)context .HttpContext.RequestServices.GetRequiredService<IHttpExceptionStatusCodeFinder>() .GetStatusCode(context.HttpContext, context.Exception); //获取返回result对象,可以重写自定义返回result var exceptionHandlingOptions = context.HttpContext.RequestServices.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value; var exceptionToErrorInfoConverter = context.HttpContext.RequestServices.GetRequiredService<IExceptionToErrorInfoConverter>(); var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); //打印日志 var logLevel = context.Exception.GetLogLevel(); var remoteServiceErrorInfoBuilder = new StringBuilder(); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); //remoteServiceErrorInfoBuilder.AppendLine(remoteServiceErrorInfo); var logger = context.HttpContext.RequestServices.GetService<ILogger<AbpExceptionFilter>>(); logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); logger.LogException(context.Exception, logLevel); //await context.HttpContext.RequestServices.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception)); context.Exception = null; //Handled! } } - 可以按BusinessException格式新增异常类型
[Serializable] public class BusinessException : Exception, IBusinessException, IHasErrorCode, IHasErrorDetails, IHasLogLevel { public string Code { get; set; } public string Details { get; set; } public LogLevel LogLevel { get; set; } public BusinessException( string code = null, string message = null, string details = null, Exception innerException = null, LogLevel logLevel = LogLevel.Warning) : base(message, innerException) { Code = code; Details = details; LogLevel = logLevel; } /// <summary> /// Constructor for serializing. /// </summary> public BusinessException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } public BusinessException WithData(string name, object value) { Data[name] = value; return this; } } - 重写IHttpExceptionStatusCodeFinder接口定义返回StatusCode
public virtual HttpStatusCode GetStatusCode(HttpContext httpContext, Exception exception) { if (exception is IHasHttpStatusCode exceptionWithHttpStatusCode && exceptionWithHttpStatusCode.HttpStatusCode > 0) { return (HttpStatusCode) exceptionWithHttpStatusCode.HttpStatusCode; } if (exception is IHasErrorCode exceptionWithErrorCode && !exceptionWithErrorCode.Code.IsNullOrWhiteSpace()) { if (Options.ErrorCodeToHttpStatusCodeMappings.TryGetValue(exceptionWithErrorCode.Code, out var status)) { return status; } } if (exception is AbpAuthorizationException) { return httpContext.User.Identity.IsAuthenticated ? HttpStatusCode.Forbidden : HttpStatusCode.Unauthorized; } //TODO: Handle SecurityException..? if (exception is AbpValidationException) { return HttpStatusCode.BadRequest; } if (exception is EntityNotFoundException) { return HttpStatusCode.NotFound; } if (exception is NotImplementedException) { return HttpStatusCode.NotImplemented; } if (exception is IBusinessException) { return HttpStatusCode.Forbidden; } return HttpStatusCode.InternalServerError; } - 重写IExceptionToErrorInfoConverter接口定义返回result
public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConverter, ITransientDependency { ///.... public RemoteServiceErrorInfo Convert(Exception exception, bool includeSensitiveDetails) { var errorInfo = CreateErrorInfoWithoutCode(exception, includeSensitiveDetails); if (exception is IHasErrorCode hasErrorCodeException) { errorInfo.Code = hasErrorCodeException.Code; } return errorInfo; } }

浙公网安备 33010602011771号