現在的開發模式很少用asp.net mvc一個項目直接操作界面和數據庫了。大部分都使用前后端分離,更多的是為了讓API支持移動端。
后端寫webapi的時候必然需要和前端約定請求值和返回值的格式,如果有異常返回應該如何識別和區分;
通過actionfilter即可實現AOP切入處理,而不需要在每個方法中處理。
/// <summary>
/// Api action統一處理過濾器
/// 處理正常返回值 {code:200,body:{}}
/// </summary>
public class ApiResponseFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
//模型驗證
if (!context.ModelState.IsValid)
{
throw new ApplicationException(context.ModelState.Values.First(p => p.Errors.Count > 0).Errors[0].ErrorMessage);
}
base.OnActionExecuting(context);
}
/// <summary>
/// 處理正常返回的結果對象,進行統一json格式包裝
/// 異常只能交由ExceptionFilterAttribute 去處理
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result != null)
{
var result = context.Result as ObjectResult;
JsonResult newresult;
if (context.Result is ObjectResult)
{
newresult = new JsonResult(new { code = 200, body = result.Value });
}
else if (context.Result is EmptyResult)
{
newresult = new JsonResult(new { code = 200, body = new { } });
}
else
{
throw new Exception($"未經處理的Result類型:{ context.Result.GetType().Name}");
}
context.Result = newresult;
}
base.OnActionExecuted(context);
}
}
/// <summary>
/// api異常統一處理過濾器
/// 系統級別異常 500 應用級別異常501
/// </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)
{
int code = 0;
string message = "";
string innerMessage = "";
//應用程序業務級異常
if (ex is ApplicationException)
{
code = 501;
message = ex.Message;
}
else
{
// exception 系統級別異常,不直接明文顯示的
code = 500;
message = "發生系統級別異常";
innerMessage = ex.Message;
}
if (ex.InnerException != null && ex.Message != ex.InnerException.Message)
innerMessage += "," + ex.InnerException.Message;
return new JsonResult(new { code, message, innerMessage });
}
}