• 2022年10月26日

Furion的统一返回值模型应用

编写webapi就会涉及到返回结果给客户端(IActionResult),客户端根据返回的结果判断当前接口调用情况再给用户相应的提示或界面。

如果没有一个统一的结果结构,后期维护时或新成员介入开发时会增加开发难度,Furion提供了一个统一返回值模型。

一、定义返回模型ApiResultProvider.cs


using Furion.UnifyResult;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Http;
using Furion;
using Furion.DataValidation;
using Furion.FriendlyException; 
using System; 

    [UnifyModel(typeof(ApiResult<>))]
    public class ApiResultProvider : IUnifyResultProvider
    {
        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            if (metadata.ErrorCode == null)
            {  //添加了个自定义错误返回值
                return new JsonResult(ApiResult(StatusCodes.Status200OK, data:metadata.Data, errors: metadata.Errors)
                    , UnifyContext.GetSerializerSettings(context)); // 当前行仅限 Furion 4.6.6+ 使用

            }
            else
            {

                return new JsonResult(ApiResult(metadata.StatusCode, data: metadata.Data, errors: metadata.Errors)
                    , UnifyContext.GetSerializerSettings(context)); // 当前行仅限 Furion 4.6.6+ 使用
            }
        }
        public IActionResult OnSucceeded(ActionExecutedContext context, object data)
        {
            return new JsonResult(ApiResult(StatusCodes.Status200OK, true, data)
                , UnifyContext.GetSerializerSettings(context)); // 当前行仅限 Furion 4.6.6+ 使用
        }
        public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
        { 
            return new JsonResult(ApiResult(metadata.StatusCode ?? StatusCodes.Status400BadRequest, data: metadata.Data, errors: metadata.ValidationResult)
               , UnifyContext.GetSerializerSettings(context)); // 当前行仅限 Furion 4.6.6+ 使用
        }
        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(ApiResult(statusCode, errors: "401 Unauthorized")
                        , App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
                    break;
                // 处理 403 状态码
                case StatusCodes.Status403Forbidden:
                    await context.Response.WriteAsJsonAsync(ApiResult(statusCode, errors: "403 Forbidden")
                        , App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
                    break;
                default: break;
            }
        }


        /// <summary>
        /// 返回 RESTful 风格结果集
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="success"></param>
        /// <param name="data"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static ApiResult<object> ApiResult(int statusCode, bool success = default, object data = default, object errors = default)
        {
            return new ApiResult<object>
            {
                StatusCode = statusCode,
                Success = success,
                Data = data,
                Errors = errors,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };
        }
    }
    public class ApiResult<T>
    {
        /// <summary>
        /// 数据
        /// </summary>
        public T Data { get; set; }
        /// <summary>
        /// 状态码
        /// </summary>
        public int? StatusCode { get; set; } 
        /// <summary>
        /// 执行成功
        /// </summary>
        public bool Success { get; set; }
        /// <summary>
        /// 错误信息
        /// </summary>
        public object Errors { get; set; }
        /// <summary>
        /// 附加数据
        /// </summary>
        public object Extras { get; set; }
        /// <summary>
        /// 时间戳
        /// </summary>
        public long Timestamp { get; set; }
    }

二、Startup.cs配置

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers()
                    .AddInjectWithUnifyResult<ApiResultProvider>();
        }

三、使用


[DynamicApiController]
public class UserApi
{
    public IActionResult Test()
    {
        if(false)
        {
           throw new Exception("出错啦");
         }
        return new JsonResult(new { text="Test"});
    }
}

使用的时候,要返回自定义的错误内容可以通过throw new Exception方式将错误内容传递到OnException,因为这样操作没有设定ErrorCode,所以可以进行处理(如上面红色字部分)。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注