有没有什么办法使用错误信息格式工厂并且同时返回验证结果?

来源:15-8 【应用】处理400级别错误信息

孔令瑞

2023-01-13

视频中的方式

图片描述
图片描述

这种方式存在两个可优化的点

1:可以使用之前课程讲过的错误格式工厂。
2:如果TouristRouteResourceParameters有其他验证,是否可以一次请求同时返回验证失败的信息。

期望同时返回的验证结果

{
    "errors": {
        "rating": [
            "The Rating field is required."
        ],
        "keyword": [
            "The Keyword field is required."
        ],
        "orderby": [
            "请输入正确的排序参数."
        ]
    },
    "type": "验证",
    "title": "数据验证失败",
    "status": 422,
    "detail": "查看详细说明",
    "instance": "/api/touristRoutes",
    "traceId": "0HMNL7KH2941D:00000002"
}

根据期望结果进行以下两种思路的尝试

方式1(失败):尝试自定义验证继承ValidationAttribute

错误信息:创建类时出现错误信息,泛型类型不能从System类派生,因为它是一个属性类
网上查阅了很多资料,还是无法传递<TSource,TDestination>可供类内部使用
图片描述

方式2(半失败):尝试TouristRouteResourceParameters继承IValidatableObject

给Keyword,Rating增加了 [Required]并且实现了IValidatableObject的Validate方法

using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Xiecheng.API.Dto;
using Xiecheng.API.Models;
using Xiecheng.API.Services;

namespace Xiecheng.API.ResourceParameters
{
    /// <summary>
    /// 旅游路线查询参数处理器类
    /// </summary>
    public class TouristRouteResourceParameters : IValidatableObject
    {
        /// <summary>
        /// 属性映射服务
        /// </summary>
        public readonly IPropertyMappingService PropertyMappingService;

        /// <summary>
        /// 构造方法
        /// </summary>
        public TouristRouteResourceParameters()
        {
            PropertyMappingService = new PropertyMappingService();
        }

        /// <summary>
        /// 标题
        /// </summary>
        [Required]
        public string? Keyword { get; set; }

        /// <summary>
        /// 评分方式
        /// </summary>
       
        public string? RatingOperator { get; set; }

        /// <summary>
        /// 评分值
        /// </summary>
        public int? RatingValue { get; set; }

        /// <summary>
        /// 评分
        /// </summary>
        private string? _rating;

        /// <summary>
        /// 排序
        /// </summary>
        public string? OrderBy { get; set; }

        /// <summary>
        /// 评分
        /// </summary>
        [Required]
        public string? Rating
        {
            get => _rating;
            set
            {
                if (!string.IsNullOrWhiteSpace(value))
                {
                    Regex regex = new Regex(@"([A-Za-z0-9\-]+)(\d+)");
                    Match match = regex.Match(value);
                    if (match.Success)
                    {
                        RatingOperator = match.Groups[1].Value;
                        RatingValue = Int32.Parse(match.Groups[2].Value);
                    }
                }

                _rating = value;
            }
        }

        #region 验证
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="validationContext">验证上下文</param>
        /// <returns></returns>
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (!PropertyMappingService.IsMappingExists<TouristRouteDto, TouristRoute>(OrderBy))
            {
                yield return new ValidationResult(
                    "请输入正确的排序参数",
                    new[] { "TouristRouteResourceParameters" }
                );
            }
        }
        #endregion
    }
}

请求1
图片描述
请求2
图片描述
虽然可以完成使用错误信息格式工厂的优化,但是无法在一次请求内同时返回DataAnnotations的属性验证和类IValidatableObject验证,查阅资料后知道这两者触发过程不同,但是没找到如何设置能同时触发

现在我想知道有没有任何一种方法能够同时完成两个优化?望解答

写回答

1回答

阿莱克斯刘

2023-01-30

看了你的代码,感觉你的思路已经很接近了,你可以考虑一下通过给OrderBy属性添加自定义ValidationAttribute来实现你的需求。

namespace Xiecheng.API.ResourceParameters
{
    public class TouristRouteResourceParameters
    {
        ...
        [OrderbyValidataion]
        public string? OrderBy { get; set; }
        ...
    }
}
        
public OrderbyValidataionAttribute: ValidationAttribute 
{
    ...
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //重写这个方法
    }
    ...
}

你先尝试一下,如果遇到瓶颈,欢迎随时联系我,我们可以一起研究,qq:382231334(请注明你的名字)


1
1
孔令瑞
这种自定义特性的方式无法传递,因为泛型类型不能从System类派生,之前课程是使用来确定使用哪组属性映射,qq我加了,麻烦通过一下
2023-02-06
共1条回复

.Net 开发电商后端API 从0到精通RESTful

. Net 实战+RESTful思想纵深课程,开发优雅RESTful风格API。

977 学习 · 547 问题

查看课程