Мой 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"
},
]
}