我是数据注释的新手。我想知道是否有可能(以及如何)动态添加一些验证。解释原因是非常广泛的,但我有一个ViewModel在创建时接收和反对。在那个对象中,我必须检查一些属性,并根据其值,我应该有或没有一些验证。
一个例子:
public class ProfileViewModel
{
[Required(ErrorMessage = "The field {0} is required")]
[Display(Name = "Client Code")]
public int ClientCode { get; set; }
[Required(ErrorMessage = "The field {0} is required")]
[StringLength(100, ErrorMessage = "The field {0} must have up to 100 characters.")]
[Display(Name = "Company")]
public string Company { get; set; }
[StringLength(50, ErrorMessage = "The field {0} must have up to 50 characters.")]
[Display(Name = "Name")]
public string Name { get; set; }
[StringLength(50, ErrorMessage = "The field {0} must have up to 50 characters.")]
[Display(Name = "LastName")]
public string LastName { get; set; }
public ProfileViewModel(User usr)
{
if (usuario.ClientCode != null)
{
ClientCode = Convert.ToInt32(usr.ClientCode);
}
else
{
//ClientCode and Company are not yet required.
//Name and LastName are now required.
}
Company = usr.Company;
Name = usr.Name;
LastName = usr.LastName;
}
}
答案 0 :(得分:9)
我认为实现我想要的最简单的方法是实施IValidatableObject
:
public class Product : IValidatableObject
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Prop1 < Prop2)
yield return new ValidationResult("Property 1 can't be less than Property 2");
}
}
答案 1 :(得分:5)
自定义属性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class CustomRequiredIfAttribute : CustomAttribute
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public CustomRequiredIfAttribute()
{
}
public CustomRequiredIfAttribute(string dependentProperty, object targetValue)
: base()
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
}
自定义 RequiredIfValidator
using System;
using System.Collections.Generic;
using System.Web.Mvc;
namespace Custom.Web.Validation
{
public class RequiredIfValidator : DataAnnotationsModelValidator<CustomRequiredIfAttribute>
{
public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, CustomRequiredIfAttribute attribute)
: base(metadata, context, attribute)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return base.GetClientValidationRules();
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
// get a reference to the property this validation depends upon
var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
if (field != null)
{
// get the value of the dependent property
object value = field.GetValue(container, null);
// compare the value against the target value
if (this.IsEqual(value) || (value == null && Attribute.TargetValue == null))
{
// match => means we should try validating this field
if (!Attribute.IsValid(Metadata.Model))
{
// validation failed - return an error
yield return new ModelValidationResult { Message = ErrorMessage };
}
}
}
}
private bool IsEqual(object dependentPropertyValue)
{
bool isEqual = false;
if (Attribute.TargetValue != null && Attribute.TargetValue.GetType().IsArray)
{
foreach (object o in (Array)Attribute.TargetValue)
{
isEqual = o.Equals(dependentPropertyValue);
if (isEqual)
{
break;
}
}
}
else
{
isEqual = Attribute.TargetValue.Equals(dependentPropertyValue);
}
return isEqual;
}
}
}
注册自定义DataAnnotationsModelValidatorProvider
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRequiredIfAttribute), typeof(RequiredIfValidator));
在 ViewModel
[CustomRequiredIf("CategoryId", 3, ErrorMessageResourceName = GlobalResourceLiterals.AccountGroup_Required)]
public string AccountGroup { get; set; }
答案 2 :(得分:1)