我读过一些文章,但现在无法找到它,在MVC 3中并没有真正需要创建一个Validator,只有属性。这是真的?我确实说我发现这个属性上有IClientValidatable,令人困惑。那么,如果注释具有客户端脚本名称(IClientValidatable),并且验证(ValidationAttribute IsValid)的能力,DataAnnotationsModelValidator类会做什么?MVC 2与MVC 3自定义验证属性使用DataAnnotationsModelValidatorProvider.RegisterAdapter
如果我不必在全球范围内使用Validator注册Attribute,那将会非常好。这可以做到吗?我读了一些不好的建议吗?
编辑:有趣的是,我只是通过排除验证器来测试它,把所有的逻辑放在IsValid中,它工作的很好。我想唯一可能会丢失的是控制器上下文,但我不确定这在验证中是有用的。如果我需要服务,则IsValid具有ValidationContext,其中包含ServiceContainer。任何真正的缺点,我不在这里接受?
编辑2: 我将开始与从这个例子的验证:http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx
的属性:
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "requiredifattribute"
};
modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty);
yield return modelClientValidationRule;
}
}
确认者:
public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute>
{
public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute)
: base(metadata, context, attribute)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return base.GetClientValidationRules();
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
if (field != null)
{
var value = field.GetValue(container, null);
if ((value == null && Attribute.TargetValue == null) ||
(value.Equals(Attribute.TargetValue)))
{
if (!Attribute.IsValid(Metadata.Model))
yield return new ModelValidationResult { Message = ErrorMessage };
}
}
}
}
利用上述当前代码,我需要在Global.asax.cs文件中注册:
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute), typeof(RequiredIfValidator));
但是,如果我移动到一切只是属性,我没有进行注册:
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty);
if (field != null)
{
var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
if ((dependentValue == null && TargetValue == null) ||
(dependentValue.Equals(TargetValue)))
{
if (!innerAttribute.IsValid(value))
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "requiredifattribute"
};
modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty);
yield return modelClientValidationRule;
}
}
有没有用代码替代所有其他代码的最后一位的问题呢?我为什么要保留验证器类?
你在哪里阅读这个建议? –
我希望我能找到它,但我不能。这更多是对某个人的帖子的评论。你怎么看待这件事? – CrazyDart
目前我不认为什么,因为我仍然试图了解问题是什么。我只是希望看到更多的上下文,特定的代码示例等等,这就是为什么我要求源代码以尝试查看更多上下文,因为您在问题中没有提供足够的内容。希望你会提供一些特定的代码示例来说明你遇到的问题。 –