/// <summary> /// 处理规范化结果 /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 排除 Mvc 视图 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (typeof(Controller).IsAssignableFrom(actionDescriptor.ControllerTypeInfo)) { await next(); return; } var actionExecutedContext = await next(); // 如果没有异常再执行 if (actionExecutedContext.Exception == null && !UnifyContext.IsSkipOnSuccessUnifyHandler(actionDescriptor.MethodInfo, out var unifyResult)) { // 处理规范化结果 if (unifyResult != null && context.Result == null) { var result = unifyResult.OnSucceeded(actionExecutedContext); if (result != null) { actionExecutedContext.Result = result; } } } }
/// <summary> /// 成功返回值 /// </summary> /// <param name="context"></param> /// <returns></returns> public IActionResult OnSucceeded(ActionExecutedContext context) { object data; // 处理内容结果 if (context.Result is ContentResult contentResult) { data = contentResult.Content; } // 处理对象结果 else if (context.Result is ObjectResult objectResult) { data = objectResult.Value; } else if (context.Result is EmptyResult) { data = null; } else { return(null); } return(new JsonResult(new RESTfulResult <object> { StatusCode = context.Result is EmptyResult ? StatusCodes.Status204NoContent : StatusCodes.Status200OK, // 处理没有返回值情况 204 Succeeded = true, Data = data, Errors = null, Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() })); }
/// <summary> /// 处理规范化结果 /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 执行 Action 并获取结果 var actionExecutedContext = await next(); // 如果出现异常,则不会进入该过滤器 if (actionExecutedContext.Exception != null) { return; } // 获取控制器信息 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; // 判断是否支持 MVC 规范化处理 if (!UnifyContext.CheckSupportMvcController(context.HttpContext, actionDescriptor, out _)) { return; } // 判断是否跳过规范化处理 if (UnifyContext.CheckSucceededNonUnify(actionDescriptor.MethodInfo, out var unifyResult)) { return; } // 处理 BadRequestObjectResult 类型规范化处理 if (actionExecutedContext.Result is BadRequestObjectResult badRequestObjectResult) { // 解析验证消息 var validationMetadata = ValidatorContext.GetValidationMetadata(badRequestObjectResult.Value); var result = unifyResult.OnValidateFailed(context, validationMetadata); if (result != null) { actionExecutedContext.Result = result; } // 打印验证失败信息 App.PrintToMiniProfiler("validation", "Failed", $"Validation Failed:\r\n{validationMetadata.Message}", true); } else { IActionResult result = default; // 检查是否是有效的结果(可进行规范化的结果) if (UnifyContext.CheckVaildResult(actionExecutedContext.Result, out var data)) { result = unifyResult.OnSucceeded(actionExecutedContext, data); } // 如果是不能规范化的结果类型,则跳过 if (result == null) { return; } actionExecutedContext.Result = result; } }
/// <summary> /// 中间件执行方法 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task InvokeAsync(HttpContext context) { await _next(context); // 处理规范化结果 if (!UnifyContext.IsSkipUnifyHandlerOnSpecifiedStatusCode(context, out var unifyResult)) { await unifyResult.OnResponseStatusCodes(context, context.Response.StatusCode, _options); } }
/// <summary> /// 验证失败返回值 /// </summary> /// <param name="context"></param> /// <param name="modelStates"></param> /// <param name="validationResults"></param> /// <param name="validateFailedMessage"></param> /// <returns></returns> public IActionResult OnValidateFailed(ActionExecutingContext context, ModelStateDictionary modelStates, Dictionary <string, IEnumerable <string> > validationResults, string validateFailedMessage) { return(new JsonResult(new RESTfulResult <object> { StatusCode = StatusCodes.Status400BadRequest, Succeeded = false, Data = null, Errors = validationResults, Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() })); }
/// <summary> /// 返回 RESTful 风格结果集 /// </summary> /// <param name="statusCode"></param> /// <param name="succeeded"></param> /// <param name="data"></param> /// <param name="errors"></param> /// <returns></returns> private static RESTfulResult <object> RESTfulResult(int statusCode, bool succeeded = default, object data = default, object errors = default) { return(new RESTfulResult <object> { StatusCode = statusCode, Succeeded = succeeded, Data = data, Errors = errors, Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }); }
/// <summary> /// 异常返回值 /// </summary> /// <param name="context"></param> /// <returns></returns> public IActionResult OnException(ExceptionContext context) { // 解析异常信息 var(StatusCode, _, Errors) = UnifyContext.GetExceptionMetadata(context); return(new JsonResult(new RESTfulResult <object> { StatusCode = StatusCode, Succeeded = false, Data = null, Errors = Errors, Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() })); }
/// <summary> /// 中间件执行方法 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task InvokeAsync(HttpContext context) { await _next(context); // 只有请求错误(短路状态码)才支持规范化处理 if (context.Response.StatusCode < 400 || context.Response.StatusCode == 404) { return; } // 处理规范化结果 if (!UnifyContext.CheckStatusCodeNonUnify(context, out var unifyResult)) { await unifyResult.OnResponseStatusCodes(context, context.Response.StatusCode, context.RequestServices.GetService <IOptions <UnifyResultSettingsOptions> >()?.Value); } }
/// <summary> /// 处理规范化结果 /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 排除 Mvc 视图 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (typeof(Controller).IsAssignableFrom(actionDescriptor.ControllerTypeInfo)) { await next(); return; } var actionExecutedContext = await next(); // 如果没有异常再执行 if (actionExecutedContext.Exception == null && !UnifyContext.IsSkipUnifyHandlerOnSucceedReturn(actionDescriptor.MethodInfo, out var unifyResult)) { // 处理规范化结果 if (unifyResult != null) { // 处理 BadRequestObjectResult 验证结果 if (actionExecutedContext.Result is BadRequestObjectResult badRequestObjectResult) { // 解析验证消息 var(validationResults, validateFaildMessage, modelState) = ValidatorContext.OutputValidationInfo(badRequestObjectResult.Value); var result = unifyResult.OnValidateFailed(context, modelState, validationResults, validateFaildMessage); if (result != null) { actionExecutedContext.Result = result; } // 打印验证失败信息 App.PrintToMiniProfiler("validation", "Failed", $"Validation Failed:\r\n{validateFaildMessage}", true); } else { var result = unifyResult.OnSucceeded(actionExecutedContext); if (result != null) { actionExecutedContext.Result = result; } } } } }
/// <summary> /// 处理输出状态码 /// </summary> /// <param name="context"></param> /// <param name="statusCode"></param> /// <param name="options"></param> /// <returns></returns> public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultStatusCodesOptions options) { // 设置响应状态码 UnifyContext.SetResponseStatusCodes(context, statusCode, options); switch (statusCode) { // 处理 401 状态码 case StatusCodes.Status401Unauthorized: await context.Response.WriteAsJsonAsync(new RESTfulResult <object> { StatusCode = StatusCodes.Status401Unauthorized, Succeeded = false, Data = null, Errors = "401 Unauthorized", Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }); break; // 处理 403 状态码 case StatusCodes.Status403Forbidden: await context.Response.WriteAsJsonAsync(new RESTfulResult <object> { StatusCode = StatusCodes.Status403Forbidden, Succeeded = false, Data = null, Errors = "403 Forbidden", Extras = UnifyContext.Take(), Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }); break; default: break; } }
/// <summary> /// 特定状态码返回值 /// </summary> /// <param name="context"></param> /// <param name="statusCode"></param> /// <param name="unifyResultSettings"></param> /// <returns></returns> public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings) { // 设置响应状态码 UnifyContext.SetResponseStatusCodes(context, statusCode, unifyResultSettings); switch (statusCode) { // 处理 401 状态码 case StatusCodes.Status401Unauthorized: await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, errors : "401 Unauthorized") , App.GetOptions <JsonOptions>()?.JsonSerializerOptions); break; // 处理 403 状态码 case StatusCodes.Status403Forbidden: await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, errors : "403 Forbidden") , App.GetOptions <JsonOptions>()?.JsonSerializerOptions); break; default: break; } }