ASP.NET MVC: пользовательская проверка с помощью DataAnnotation
У меня есть модель с 4 свойствами, которые имеют тип string. Я знаю, что вы можете проверить длину одного свойства с помощью StringLength аннотации. Однако я хочу проверить длину 4 Свойства в сочетании.
какой способ в MVC, чтобы сделать это с помощью аннотаций данных?
Я спрашиваю об этом, потому что я новичок в MVC и хочу сделать это правильно, прежде чем принимать собственное решение.
6 ответов:
вы можете написать пользовательский атрибут проверки:
public class CombinedMinLengthAttribute: ValidationAttribute { public CombinedMinLengthAttribute(int minLength, params string[] propertyNames) { this.PropertyNames = propertyNames; this.MinLength = minLength; } public string[] PropertyNames { get; private set; } public int MinLength { get; private set; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty); var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<string>(); var totalLength = values.Sum(x => x.Length) + Convert.ToString(value).Length; if (totalLength < this.MinLength) { return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); } return null; } }
и тогда у вас может быть модель представления и украсить ею одно из своих свойств:
public class MyViewModel { [CombinedMinLength(20, "Bar", "Baz", ErrorMessage = "The combined minimum length of the Foo, Bar and Baz properties should be longer than 20")] public string Foo { get; set; } public string Bar { get; set; } public string Baz { get; set; } }
собственной обоснованной модели
ваша модель должна реализовать интерфейс
IValidatableObject
. Поместите код проверки вValidate
способ:public class MyModel : IValidatableObject { public string Title { get; set; } public string Description { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Title == null) yield return new ValidationResult("*", new [] { nameof(Title) }); if (Description == null) yield return new ValidationResult("*", new [] { nameof(Description) }); } }
обратите внимание: это на стороне сервера проверка. Он не работает на стороне клиента. Проверка будет выполнена только после отправки формы.
ExpressiveAnnotations дает вам такую возможность:
[Required] [AssertThat("Length(FieldA) + Length(FieldB) + Length(FieldC) + Length(FieldD) > 50")] public string FieldA { get; set; }
Справочная информация:
проверки модели необходимы для обеспечения того, что полученные данные мы получаем действительны и правильны, так что мы можем сделать дальнейшую обработку с этими данными. Мы можем проверить модель в методе действия. Встроенные атрибуты проверки-Compare, Range, RegularExpression, Required, StringLength. Однако у нас могут быть сценарии, в которых нам требуются атрибуты проверки, отличные от встроенных.
Выборочная Проверка Атрибуты
public class EmployeeModel { [Required] [UniqueEmailAddress] public string EmailAddress {get;set;} public string FirstName {get;set;} public string LastName {get;set;} public int OrganizationId {get;set;} }
чтобы создать пользовательский атрибут проверки, вам придется наследовать этот класс от ValidationAttribute.
public class UniqueEmailAddress : ValidationAttribute { private IEmployeeRepository _employeeRepository; [Inject] public IEmployeeRepository EmployeeRepository { get { return _employeeRepository; } set { _employeeRepository = value; } } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var model = (EmployeeModel)validationContext.ObjectInstance; if(model.Field1 == null){ return new ValidationResult("Field1 is null"); } if(model.Field2 == null){ return new ValidationResult("Field2 is null"); } if(model.Field3 == null){ return new ValidationResult("Field3 is null"); } return ValidationResult.Success; } }
надеюсь, что это помогает. Ура !
ссылки
чтобы улучшить ответ Дарина, он может быть немного короче:
public class UniqueFileName : ValidationAttribute { private readonly NewsService _newsService = new NewsService(); public override bool IsValid(object value) { if (value == null) { return false; } var file = (HttpPostedFile) value; return _newsService.IsFileNameUnique(file.FileName); } }
модель:
[UniqueFileName(ErrorMessage = "This file name is not unique.")]
обратите внимание, что сообщение об ошибке не требуется, в противном случае ошибка будет пустой.
немного поздно, чтобы ответить, но для тех, кто ищет. Вы можете легко сделать это, используя дополнительное свойство с аннотацией данных:
public string foo { get; set; } public string bar { get; set; } [MinLength(20, ErrorMessage = "too short")] public string foobar { get { return foo + bar; } }
это все слишком реально. Если вы действительно хотите отобразить в определенном месте ошибку проверки, вы можете добавить это в своем представлении:
@Html.ValidationMessage("foobar", "your combined text is too short")
делаю это в представлении может пригодиться, если вы хотите сделать локализацию.
надеюсь, что это помогает!