Как создать пользовательские валидаторы аннотаций данных
Желая создать пользовательскую проверку аннотации данных. Есть ли полезные руководства / образцы о том, как их создать?
Во-первых:
StringLength с минимальной и максимальной длиной. Я знаю, что.NET 4 может сделать это, но хочу сделать то же самое в.NET 3.5, если возможно, имея возможность определять только минимальную длину (как минимум x символов), только максимальную длину (до x символов) или оба (между x и y символами).
Во-вторых:
Валидация с использованием арифметики модуля - если число является допустимой длиной, я хочу проверить с использованием алгоритма Modulus 11 (я уже реализовал его в JavaScript, поэтому я предполагаю, что это будет просто перенос?)
Обновить:
Решил вторую проблему - просто скопировал реализацию JavaScript и внес несколько изменений, поэтому решение для этого не нужно.
3 ответа
Чтобы создать пользовательский валидатор аннотаций данных, следуйте этим рекомендациям:
- Ваш класс должен наследовать от
System.ComponentModel.DataAnnotations.ValidationAttribute
учебный класс. - Override
bool IsValid(object value)
метод и реализовать логику проверки внутри него.
Вот и все.
ВАЖНО Внимание
Иногда разработчики проверяют, что значение не равно нулю / пусто, и возвращают false. Это обычно некорректное поведение, потому что это на Required
валидатор, чтобы проверить, что означает, что ваши пользовательские валидаторы должны только проверять ненулевые данные, но возвращать true
в противном случае (см. пример). Это сделает их пригодными для использования в обязательных (обязательных) и необязательных полях.
пример
public class StringLengthRangeAttribute : ValidationAttribute
{
public int Minimum { get; set; }
public int Maximum { get; set; }
public StringLengthRangeAttribute()
{
this.Minimum = 0;
this.Maximum = int.MaxValue;
}
public override bool IsValid(object value)
{
string strValue = value as string;
if (!string.IsNullOrEmpty(strValue))
{
int len = strValue.Length;
return len >= this.Minimum && len <= this.Maximum;
}
return true;
}
}
Все свойства могут быть установлены в атрибуте, как вы хотите их установить.
Некоторые примеры:
[Required]
[StringLengthRange(Minimum = 10, ErrorMessage = "Must be >10 characters.")]
[StringLengthRange(Maximum = 20)]
[Required]
[StringLengthRange(Minimum = 10, Maximum = 20)]
Когда конкретное свойство не установлено, его значение устанавливается в конструкторе, поэтому оно всегда имеет значение. В приведенных выше примерах использования я намеренно добавил Required
валидатор, так что он синхронизирован с вышеупомянутым предостережением, которое я написал.
Важный
Таким образом, этот валидатор все равно будет работать со значением вашей модели, которое не требуется, но когда оно присутствует, оно проверяется (представьте текстовое поле в веб-форме, это не обязательно, но если пользователь вводит значение в, оно должно быть действительным),
Использовать CustomValidationAttribute
вместе с функцией проверки с подписью
public static ValidationResult Validate(MyType x, ValidationContext context)
Пример (для строкового свойства)
using System.ComponentModel.DataAnnotations;
public class MyClass
{
[CustomValidation(typeof(MyClass), "Validate")]
public string MyProperty { get; set; }
public static ValidationResult Validate(string x, ValidationContext context)
{
return (x == "valid")
? new ValidationResult(null)
: ValidationResult.Success;
}
}
Я знаю, что это действительно старая тема, но у меня возникли проблемы с поиском ответа, который я действительно хотел, пока я не нашел этот ответ: /questions/3622929/obrabotka-validatsii-modelstate-v-aspnet-web-api/55050632#55050632
Напомним, что вам нужно настроить службу при запуске, создав соответствующие объекты, которые обрабатывают ошибку, которую вы хотите вернуть:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = (context) =>
{
var errors = context.ModelState.Values.SelectMany(x => x.Errors.Select(p => new ErrorModel()
{
ErrorCode = ((int)HttpStatusCode.BadRequest).ToString(CultureInfo.CurrentCulture),
ErrorMessage = p.ErrorMessage,
ServerErrorMessage = string.Empty
})).ToList();
var result = new BaseResponse
{
Error = errors,
ResponseCode = (int)HttpStatusCode.BadRequest,
ResponseMessage = ResponseMessageConstants.VALIDATIONFAIL,
};
return new BadRequestObjectResult(result);
};
});