/// <summary>
/// 封装工厂后台的返回数据
/// </summary>
public class FactoryResultFilterAttribute : ResultFilterAttribute
{
/// <summary>
/// 如果只是返回Task的接口,会自动封装成CommonResponse
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (!context.ActionDescriptor.EndpointMetadata.Any(x => x.GetType().Equals(typeof(NoResultFilterAttribute))))
{
if (context.Result.GetType() == typeof(EmptyResult))
{
var res = new CommonResponse();
context.Result = new JsonResult(res)
{
ContentType = "application/json",
StatusCode = 200,
};
}
else if ((context.HttpContext.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase) || context.HttpContext.Request.Method.Equals("POST", StringComparison.OrdinalIgnoreCase)) && context.Result is ObjectResult)
{
var result = (ObjectResult)context.Result;
var res = new CommonResponse<Object>
{
Data = result.Value,
};
context.Result = new JsonResult(res)
{
ContentType = "application/json",
StatusCode = 200,
};
}
}
await next.Invoke();
}
}
1. 统一包装返回参数,使用过滤器ResultFilterAttribute来实现,OnResultExecutionAsync中可以处理所有Get和Post类型接口返回的数据,用CommonResponse类包装一下。
CommonResponse类主要用来返回Code(200表示成功)和Message(访问失败的原因)
2. 这里配合ExceptionFilterAttribute一起用,用来捕捉错误BusinessException,这样业务代码出现错误后,直接throw new BusinessException("金额不能为0"),就会被过滤器自动捕捉并封装成CommonResponse返回给前端,方便前端统一处理。
/// <summary>
/// 业务类型错误
/// </summary>
public class BusinessException : Exception
{
public BusinessException() : base("数据不存在")
{
}
public BusinessException(string message) : base(message)
{
}
}
/// <summary>
/// 通用的异常处理
/// </summary>
public class FactoryExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly ILogger<FactoryExceptionFilterAttribute> _logger;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
public FactoryExceptionFilterAttribute(ILogger<FactoryExceptionFilterAttribute> logger)
{
_logger = logger;
}
/// <summary>
/// 通用api接口异常处理
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override Task OnExceptionAsync(ExceptionContext context)
{
if (!context.ExceptionHandled)
{
Exception exception = context.Exception;
if (exception is BusinessException)
{
context.Result = new JsonResult(new CommonResponse(exception.Message));
}
else if (exception is ValidationException)
{
ValidationException? e = exception as ValidationException;
context.Result = new JsonResult(new CommonResponse(e?.Errors.FirstOrDefault()?.ErrorMessage ?? ""));
}
else
{
var res = new CommonResponse
{
Code = ResCode.ServerError,
Message = "请求错误"
};
exception.Log(context.HttpContext);
_logger.LogError(exception.Message);
context.Result = new JsonResult(res);
}
}
context.ExceptionHandled = true;
return Task.CompletedTask;
}
}