ASP.NET MVC:通过DataAnnotation进行自定义validation

我有一个具有4个属性的types为string的模型。 我知道你可以通过使用StringLength注解来validation单个属性的长度。 不过我想validation4个属性的长度。

什么是MVC的方式来做到这一点与数据注释?

我这样问是因为我是MVC的新手,想在做出自己的解决scheme之前正确地做到这一点。

你可以写一个自定义的validation属性:

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; } } 

自我validation的模型

你的模型应该实现一个接口IValidatableObject 。 把你的validation码放在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) }); } } 

请注意:这是服务器端validation。 它在客户端不起作用。 您只有在提交表单后才能执行validation。

expression注释给你这样一个可能性:

 [Required] [AssertThat("Length(FieldA) + Length(FieldB) + Length(FieldC) + Length(FieldD) > 50")] public string FieldA { get; set; } 

背景:

需要进行模型validation,以确保收到的数据是有效和正确的,以便我们可以使用此数据进一步处理。 我们可以在操作方法中validation模型。 内置的validation属性是Compare,Range,RegularExpression,Required,StringLength。 但是,我们可能会遇到这样的情况:我们需要validation属性,而不是内置属性。

自定义validation属性

 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;} } 

要创build自定义validation属性,您将必须从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; } } 

希望这可以帮助。 干杯!

参考

  • 代码项目 – ASP.NET MVC3中的自定义validation属性
  • haacked – ASP.NET MVC 2自定义validation

为了改善Darin的答案,可以缩短一点:

 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 = "Er bestaat al een afbeelding met deze naam")] 

请注意,一个错误消息是必需的,否则错误将是空的。

有点晚回答,但谁正在search。 您可以通过在数据注释中使用额外的属性来轻松完成此操作:

 public string foo { get; set; } public string bar { get; set; } [MinLength(20, ErrorMessage = "too short")] public string foobar { get { return foo + bar; } } 

这就是真的。 如果您确实想要在特定位置显示validation错误,则可以在您的视图中添加此项:

 @Html.ValidationMessage("foobar", "your combined text is too short") 

如果你想做本地化,在视图中这样做可以派上用场。

希望这可以帮助!