.net core简单引用abp vnext异常过滤
- abp在AbpAspNetCoreMvcModule里添加AbpExceptionFilter过滤器的,异常管理主要通过AbpExceptionFilter实现
123456789
public
class
AbpAspNetCoreMvcModule : AbpModule
{
//......省略若干代码
Configure<MvcOptions>(mvcOptions =>
{
mvcOptions.AddAbp(context.Services);
});
//......
}
123456public
static
void
AddAbp(
this
MvcOptions options, IServiceCollection services)
{
//...
AddActionFilters(options);
//...
}
123456private
static
void
AddActionFilters(MvcOptions options)
{
// ...
// 异常过滤器
options.Filters.AddService(
typeof
(AbpExceptionFilter));
}
- AbpExceptionFilter过滤器在AbpAspNetCoreMvcModule里添加的,可以直接用,也可以自己添加过滤器重写AbpExceptionFilter自定义Exception类型与返回result
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
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格式新增异常类型
1234567891011121314151617181920212223242526272829303132333435363738394041
[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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
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
123456789101112131415
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;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库