Bri*_*get 1 c# data-annotations asp.net-mvc-3
我在互联网上找到了一个RequiredIfAttribute,我将其修改为RequiredNotIf.该属性可以像这样使用.
[RequiredNotIf("LastName", null, ErrorMessage = "You must fill this.")]
public string FirstName { get; set; }
[RequiredNotIf("FirstName", null, ErrorMessage = "You must fill this")]
public string LastName { get; set; }
Run Code Online (Sandbox Code Playgroud)
和属性的源代码 ......
[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true)]
public class RequiredNotIfAttribute : RequiredAttribute, IClientValidatable
{
private string OtherProperty { get; set; }
private object Condition { get; set; }
public RequiredNotIfAttribute(string otherProperty, object condition)
{
OtherProperty = otherProperty;
Condition = condition;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(OtherProperty);
if (property == null)
{
return new ValidationResult(String.Format("Property {0} not found.", OtherProperty));
}
var propertyValue = property.GetValue(validationContext.ObjectInstance, null);
var conditionIsMet = !Equals(propertyValue, Condition);
return conditionIsMet ? base.IsValid(value, validationContext) : null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredif",
};
var depProp = BuildDependentPropertyId(metadata, context as ViewContext);
var targetValue = (Condition ?? "").ToString();
if (Condition != null && Condition is bool)
{
targetValue = targetValue.ToLower();
}
rule.ValidationParameters.Add("otherproperty", depProp);
rule.ValidationParameters.Add("condition", targetValue);
yield return rule;
}
private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
{
var depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(OtherProperty);
var thisField = metadata.PropertyName + "_";
if (depProp.StartsWith(thisField))
{
depProp = depProp.Substring(thisField.Length);
}
return depProp;
}
}
Run Code Online (Sandbox Code Playgroud)
这个的缺点 - 正如我所看到的 - 是属性"header"中的魔术字符串.我怎么能摆脱它?
你无法摆脱它,因为属性是元数据,值必须在编译时知道.如果你想在没有魔术字符串的情况下进行更高级的验证,我强烈建议你使用FluentValidation.NET.以声明方式使用属性执行验证是非常有限的恕我直言.只需看看你必须为标准创建的源代码的数量,以及RequiredIf或RequiredNotIf.当他们选择Data Annotations进行验证时,我不知道框架的设计者在想什么.这太荒谬了.也许在未来他们会丰富它并允许更复杂的场景,但在那之前我坚持使用FV.
归档时间: |
|
查看次数: |
703 次 |
最近记录: |