В Интернете я нашел атрибут 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; }
И исходный код для атрибута ...
[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;
}
}
Недостаток с этим - как я вижуэто - волшебная строка в атрибуте «заголовок».Как от этого избавиться?