Проверка каждой строки в коллекции с использованием атрибутов проверки - PullRequest
0 голосов
/ 30 октября 2019

Мой API имеет конечную точку POST, которая ожидает, что в теле будет представлен список значений, и каждое значение должно соответствовать базовому набору правил.

Например, ожидаемый JSON должен выглядеть следующим образом:

{
    "someReferences" : [
        "SomeRef_001", 
        "SomeRef_002", 
        "SomeRef_001"
    ]
}

В качестве аргумента мы скажем, что каждое значение здесь должно быть ровно 11 символов.

Чтобы захватить этот запрос, у меня есть простой класс:

public class SomeReferenceData 
{
    public List<string> SomeReferences { get; set; }
}

Я хотел бы использовать атрибуты проверки, чтобы проверить, что длина каждого значения в свойстве SomeReferencesсоответствует набору правил, т.е. все они имеют длину 11 символов.

Возможно ли это сделать с помощью встроенных атрибутов проверки?


Я знаю, что могу создать свой собственный атрибут проверки для этого (что-то вродениже), но я надеюсь, что есть что-то встроенное.

public class EachInCollectionAttribute : ValidationAttribute
{
    public int MinInclusiveLength { get; set; }
    public int MaxInclusiveLength { get; set; }

    public EachInCollectionAttribute() { }

    public EachInCollectionAttribute(int minInclusiveLength, int maxInclusiveLength)
    {
        MinInclusiveLength = minInclusiveLength;
        MaxInclusiveLength = maxInclusiveLength;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext.GetType().GetInterface(nameof(IEnumerable)) == null)
        {
            throw new InvalidOperationException(
                $"Type {value.GetType().Name} is not supported by the {nameof(EachInCollectionAttribute)} as it does not implement {nameof(IEnumerable)}");
        }
        foreach(var v in value as IEnumerable)
        {
            string vString = v.ToString();
            if (vString.Length <= MinInclusiveLength || vString.Length <= MaxInclusiveLength)
            {
                return new ValidationResult(
                    $"The value {vString} does does not conform to the length requirements of min {MinInclusiveLength}, max {MaxInclusiveLength}");
            }
        }
        return ValidationResult.Success;
    }
}

public class SomeReferenceData 
{
    [EachInCollection(minInclusiveLength: 11, maxInclusiveLength: 11)]
    public List<string> SomeReferences { get; set; }
}

Редактировать: Другой вариант - создать один проверяемый объект, который содержит необходимые атрибуты проверки, а затем иметь вторичный объект, которыйсодержит коллекцию из них. Например:

public class SomeReference 
{
    [Required]
    [StringLength(maximumLength: 11, MinimumLength = 11)]
    public string Value { get; set; }
}

public class SomeReferenceCollection 
{
    [Required]
    public List<SomeReference> References { get; set; }
}

Однако использование этого подхода означает, что ожидаемый JSON должен будет измениться следующим образом (чего я бы предпочел избежать):

{
    "someReferences" : [
        {
            value: "SomeRef_001"
        },
        {
            value: "SomeRef_002"
        },
        {
            value: "SomeRef_001"
        },
    ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...