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")
如果你想做本地化,在视图中这样做可以派上用场。
希望这可以帮助!