这是我在遇到同样问题时提出的解决方法。与ABP相比,解决方案与ASP.NET更相关。
首先,我在我的基本异常中创建了错误代码的字段。
事情是这样的:
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;
}
}
}
最后,更换 ABP自动注册在WebApiModule初始化中用我的实现过滤。
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>());
}
}
现在通过我的自定义例外和过滤器,我可以控制响应状态码。