0

在我们的系统中,我们有一个 entity Product,它可能有各种自定义属性。属性集可能因产品而异,并存储在 type 的字段中List<Property>。属性有不同的类型(字符串、整数、双精度)并且可能具有一些特殊特性,例如它们可能是多值的、可能是特定范围的值、给定列表中的值等。属性的值总是包含在字符串字段Value

现在我当前的问题是实现这些属性的验证,我有点坚持采用什么方法来部分表示验证结果。我必须满足的要求: - 验证的结果将被其他应用程序层使用,因此生成的 API 应该清晰且易于使用 - 每个错误都应该有不同的表示 - API 的用户应该有足够的信息来理解错误细节(例如,对于范围错误,应提供最小可能值、最大可能值和实际值)

以下是我目前考虑的方法:

  1. 类层次结构。有一个基础抽象类ValidationError,每个特定的错误都会反映在一个继承的类中。如果错误有任何细节,相应的类将有必要的字段来存储所有信息。例子:

    public abstract class ValidationError
    {
        // common fields and methods, if any
    }
    
    public class IncorrectFormatValidationError : ValidationError
    {
        // just empty class, nothing to add here
    }
    
    public class RangeValidationError : ValidationError
    {
        public object MinValue { get; set; }
    
        public object MaxValue { get; set; }
    }
    

    由于实际空类的多样性,这种方法对我来说似乎是相当多余的。此外,使用这样的 API 似乎并不正确(if (typeof(error) == typeof(RangeValidationError))- 胡说八道!)。然而,这是我想到的第一件事。

  2. 错误枚举,必要时,类层次结构。所有错误都用枚举表示。大多数情况下使用一个类ValidationError,当特定错误需要附加信息时,将创建继承者,与第一种方法基本相同。例子:

    public enum ValidationErrors
    {
        IncorrectFormat,
        ValueNotWithinRange,
        ...
    }
    
    public class ValidationError
    {
        public ValidationErrors ErrorType { get; set; } 
    
        public ValidationError(ValidationErrors type)
        {
            this.ErrorType = type;
            ...
        }
    
        // common fields and methods, if any
    }
    
    public class RangeValidationError : ValidationError
    {
        public object MinValue { get; set; }
    
        public object MaxValue { get; set; }
    
        public RangeValidationError(object minValue, object maxValue) :
            base(ValidationErrors.ValueNotWithinRange)
        {
            ...
        }
    }
    

    这种方法看起来要好得多,但也有缺点。最大的一个问题是,我们作为 API 用户无法保证当我们遇到类型 say 的错误时ValueNotWithinRange,我们正在处理 type of type RangeValidationError,如果没有 - 我们如何处理它?理想情况下,我希望有一些设计级别的功能可以防止这种情况的存在,因为我不是唯一开发 API 的人。这种方法的另一个问题是,如果大多数错误最终需要一些额外的信息,我们最终会得到相同的方法 1。

有人对这两种方法有什么想法可以分享或提出更好的方法吗?我将非常感谢任何回应。提前致谢。

4

2 回答 2

0

您可能想看看FluentValidation 之类的东西。它轻巧、直观,涵盖了许多验证场景。

如果您对 FluentValidation 使用的验证结果不满意,您始终可以将它们包装在您自己的自定义验证错误类中。至少你会免费获得很多基本功能。

于 2012-03-05T09:28:37.350 回答
0

退后一步重新考虑整个“表示验证错误的多个类”方法可能是一个好主意,因为它几乎可以保证您已经拥有验证器的层次结构。

任何验证错误都可以完美指定:

  1. 无法接受属性值的验证器
  2. 物业名称
  3. 验证失败的值

任何进一步的信息(例如范围限制、不匹配的正则表达式)都已经存在于验证器实例上,并且可以通过它访问。

那么如果只有一个如下所示的验证错误类呢:

public sealed class ValidationError
{
    public Validator Validator { get; set; }
    public string PropertyName { get; set; }
    public object AttemptedValue { get; set; }
}
于 2012-03-05T09:19:27.880 回答