现在 Web 开发比较流行前后端分离,在写 API 的过程中有很多地方需要统一处理
利用AOP可以对业务逻辑各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发效率。
Filter是延续ASP.NET MVC的产物,同样保留了五种的Filter,分别是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter。.
通过不同的Filter可以有效处理封包进出的统一处理
下面看下实际的应用
参数验证
此处所说的参数验证指的是实体类型的参数验证,通过在实体的属性上添加特性的方式来实现。
public override void OnActionExecuting(ActionExecutingContext context)
{
//模型验证
if (!context.ModelState.IsValid)
{
throw new CustomException(context.ModelState.Values.First(p => p.Errors.Count > 0).Errors[0].ErrorMessage, ReturnCode.E1000002);
}
base.OnActionExecuting(context);
}
返回值
返回值的统一处理需要下面几个步骤:
-
创建统一返回结果的实体类,所有的接口方法都返回固定格式,方便前端统一处理
-
创建过滤器,过滤器用来拦截请求,包装结果,统一输出
-
Startup 类中进行配置注册
/// <summary>
/// 处理正常返回的结果对象
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result != null)
{
var serializerSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local,
DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffzz:00",
//设置缩进
Formatting = Formatting.Indented,
//设置json格式为驼峰式
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var result = context.Result as ObjectResult;
JsonResult newresult;
if (context.Result is ObjectResult)
{
newresult = new JsonResult(new ReturnData { Message = "操作成功!", Code = ReturnCode.E10000, Data = result.Value }, serializerSettings);
}
else if (context.Result is EmptyResult)
{
newresult = new JsonResult(new ReturnData { Message = "操作成功!", Code = ReturnCode.E10000 }, serializerSettings);
}
else
{
throw new Exception($"未经处理的Result类型:{ context.Result.GetType().Name}");
}
context.Result = newresult;
}
base.OnActionExecuted(context);
}
}
异常处理
异常处理和参数验证的方式基本相同
// <summary>
/// api异常统一处理过滤器
/// </summary>
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
context.Result = BuildExceptionResult(context.Exception);
base.OnException(context);
}
/// <summary>
/// 包装处理异常格式
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
private JsonResult BuildExceptionResult(Exception ex)
{
var returnData = new ReturnData();
var exresult = ex as CustomException;
var WriteLog = true;
if (exresult != null)
{
//异常为自定义的异常
returnData.Code = exresult.ErrorCode;
returnData.Message = exresult.Message;
WriteLog = exresult.WriteLog;
}
else
{
//异常为未知异常
returnData.Code = ReturnCode.E1000001;
returnData.Message = ex.Message;
}
//TODO 日志
var serializerSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local,
DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffzz:00",
//设置缩进
Formatting = Formatting.Indented,
//设置json格式为驼峰式
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
return new JsonResult(returnData, serializerSettings);
}
}