.NET Core统一参数校验、异常处理、结果返回

我们开发接口时,一般都会涉及到参数校验、异常处理、封装结果返回等处理。如果每个后端开发在参数校验、异常处理等都是各写各的,没有统一处理的话,代码就不优雅,也不容易维护。所以,我们需要统一校验参数,统一异常处理、统一结果返回,让代码更加规范、可读性更强、更容易维护。

统一参数校验

比如我们需要入参为必填,只需要在实体类字段添加  [Required]

/// <summary>
    ///
    /// </summary>
    public class AdminInputDto
    {
        /// <summary>
        /// 账号
        /// </summary>
        [Required]
        public string UserName { get; set; }


        /// <summary>
        /// 密码
        /// </summary>
        [Required]
        public string Password { get; set; }
    }

然后再OnActionExecuting 进行验证

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);
        }

统一结果返回

统一标准的返回格式。一般一个标准的响应报文对象

code :响应状态码

message :响应结果描述

data:返回的数据

定义一个统一的返回对象模板

/// <summary>
    /// Service的返回数据
    /// </summary>
    public class ReturnData : ReturnData<object>
    {
    }


    /// <summary>
    /// Service的返回数据
    /// </summary>
    public class ReturnData<T>
    {
        /// <summary>
        /// 返回码
        /// </summary>
        public ReturnCode Code { get; set; }


        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }


        /// <summary>
        /// 结果数据
        /// </summary>
        public T Data { get; set; }


        /// <summary>
        /// 判断处理是否成功
        /// </summary>
        public bool Success
        {
            get { return ReturnCode.E10000 == Code; }
        }
    }

在控制器返回的时候,进行返回包装

/// <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);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET Core 中,我们可以使用 Data Annotations 和 FluentValidation 这两种方式来进行接口参数校验。 1. Data Annotations Data Annotations 是 .NET 中自带的一种属性验证方式。我们可以通过在接口参数上添加 Data Annotations 的方式来实现参数校验。 例如,我们可以在一个用户名参数上添加 Required 和 MaxLength 属性来实现必填和最大长度的校验: ```csharp public IActionResult Register([Required] string username, [MaxLength(20)] string password) { // ... } ``` 2. FluentValidation FluentValidation 是一种基于 Fluent API 的验证框架,它可以让我们更方便地编写、维护和扩展验证规则。 例如,我们可以创建一个 UserValidator 类来实现用户名和密码的校验: ```csharp public class UserValidator : AbstractValidator<User> { public UserValidator() { RuleFor(x => x.Username).NotEmpty().MaximumLength(20); RuleFor(x => x.Password).NotEmpty(); } } public class User { public string Username { get; set; } public string Password { get; set; } } public IActionResult Register(User user) { var validator = new UserValidator(); var result = validator.Validate(user); if (!result.IsValid) { return BadRequest(result.Errors); } // ... } ``` 在上面的示例中,我们使用 FluentValidation 定义了一个 UserValidator 类,并在其中定义了验证规则。在 Register 方法中,我们创建了一个 User 对象,并将其传递给 UserValidator 的 Validate 方法进行验证。如果验证失败,则返回 BadRequest 响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值