这是我遇到相同问题时提出的解决方法。解决方案与 ASP.NET 比 ABP 更相关。
首先,我在我的基本异常中为错误代码创建了字段。
像这样的东西:
public class BaseException : Exception
{
public int ErrorCode { get; private set; }
public BaseException() : this(500)
{
}
public BaseException(int errorCode)
{
ErrorCode = errorCode;
}
public BaseException(int errorCode, string message) : base(message)
{
ErrorCode = errorCode;
}
}
然后我介绍了以下修改过的异常过滤器,它可以识别我的BaseException
异常并读取错误代码:
namespace Abp.WebApi.ExceptionHandling
{
/// <summary>
/// Used to handle exceptions on web api controllers.
/// </summary>
public class CustomApiExceptionFilter : ExceptionFilterAttribute, ITransientDependency
{
/// <summary>
/// Reference to the <see cref="ILogger"/>.
/// </summary>
public ILogger Logger { get; set; }
/// <summary>
/// Reference to the <see cref="IEventBus"/>.
/// </summary>
public IEventBus EventBus { get; set; }
public IAbpSession AbpSession { get; set; }
private readonly IAbpWebApiModuleConfiguration _configuration;
/// <summary>
/// Initializes a new instance of the <see cref="AbpApiExceptionFilterAttribute"/> class.
/// </summary>
public CustomApiExceptionFilter(IAbpWebApiModuleConfiguration configuration)
{
_configuration = configuration;
Logger = NullLogger.Instance;
EventBus = NullEventBus.Instance;
AbpSession = NullAbpSession.Instance;
}
/// <summary>
/// Raises the exception event.
/// </summary>
/// <param name="context">The context for the action.</param>
public override void OnException(HttpActionExecutedContext context)
{
var wrapResultAttribute = (context.ActionContext.ActionDescriptor)
.GetWrapResultAttributeOrNull();
// ?? _configuration.DefaultWrapResultAttribute;
if (wrapResultAttribute == null || wrapResultAttribute.LogError)
{
LogHelper.LogException(Logger, context.Exception);
}
if (wrapResultAttribute == null || wrapResultAttribute.WrapOnError)
{
context.Response = context.Request.CreateResponse(
GetStatusCode(context),
new AjaxResponse(
SingletonDependency<ErrorInfoBuilder>.Instance.BuildForException(context.Exception),
context.Exception is Abp.Authorization.AbpAuthorizationException)
);
EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));
}
}
private HttpStatusCode GetStatusCode(HttpActionExecutedContext context)
{
if (context.Exception is Abp.Authorization.AbpAuthorizationException)
{
return AbpSession.UserId.HasValue
? HttpStatusCode.Forbidden
: HttpStatusCode.Unauthorized;
}
var customException = (context.Exception as BaseException);
if (customException != null)
return
(HttpStatusCode)customException.ErrorCode;
return
HttpStatusCode.InternalServerError;
}
}
}
最后,用我在 WebApiModule 初始化中的实现替换了ABP 自动注册过滤器。
public MyWebApiModule : AbpModule
{
public override void Initialize()
{
// ...
var filters = Configuration.Modules.AbpWebApi().HttpConfiguration.Filters;
var exceptionFilter = filters.First(h => h.Instance is AbpExceptionFilterAttribute).Instance;
filters.Remove(exceptionFilter);
filters.Add(IocManager.Resolve<CustomApiExceptionFilter>());
}
}
现在通过我的自定义异常和过滤器,我能够控制响应状态代码。