Last active
June 19, 2018 19:19
-
-
Save akatakritos/1ddf74f24a3e5d499151cd85f41a96c0 to your computer and use it in GitHub Desktop.
RequiredIf Validator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [RequiredIf("SomeOtherProperty")] -- required if the other property is true | |
// [RequiredIf("SomeIntProperty", OtherPropertyValue = 42)] -- required if the other property is 42 | |
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable | |
{ | |
public string OtherPropertyName { get; } | |
public object OtherPropertyValue { get; set; } | |
public RequiredIfAttribute(string otherPropertyName) | |
{ | |
OtherPropertyName = otherPropertyName; | |
} | |
public override bool RequiresValidationContext => true; | |
protected override ValidationResult IsValid(object value, ValidationContext validationContext) | |
{ | |
var prop = validationContext.ObjectType.GetProperty(OtherPropertyName); | |
if (prop == null) | |
throw new InvalidOperationException($"Could not find property {OtherPropertyName} on type {validationContext.ObjectType}."); | |
var otherValue = prop.GetValue(validationContext.ObjectInstance); | |
bool isRequired; | |
if (otherValue is true) | |
isRequired = true; | |
else | |
{ | |
isRequired = otherValue?.Equals(OtherPropertyValue) ?? false; | |
} | |
if (isRequired) | |
{ | |
if (value == null || (value is string s && s.Trim() == "")) | |
{ | |
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); | |
} | |
} | |
return ValidationResult.Success; | |
} | |
public override string FormatErrorMessage(string name) | |
{ | |
return string.Format(ErrorMessageString, name, OtherPropertyName); | |
} | |
// adds a data-val-requiredif attribute data-val-requireif-other="OtherPropertyName" data-val-requiredif-value="42" | |
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) | |
{ | |
var rule = new ModelClientValidationRule() | |
{ | |
ErrorMessage = FormatErrorMessage(metadata.DisplayName), | |
ValidationType = "requiredif", | |
ValidationParameters = | |
{ | |
{ | |
"other", OtherPropertyName | |
} | |
} | |
}; | |
if (OtherPropertyValue != null) | |
{ | |
rule.ValidationParameters["value"] = OtherPropertyValue.ToString(); | |
} | |
yield return rule; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.validator.addMethod('requiredif', (value, element) => { | |
const otherFieldValue = element.getAttribute('data-val-requiredif-value'); // optional | |
const otherFieldName = element.getAttribute('data-val-requiredif-other'); | |
const otherFieldElement = element.form[otherFieldName]; | |
if (otherFieldValue) { | |
if (otherFieldElement.value === otherFieldValue) { | |
// the other field matches the value, so this field is required, and | |
// thus valid only if a value is given | |
return Boolean(value); | |
} | |
// the other field does not match the value, so this element is not | |
// required, and thus always valid | |
return true; | |
} else { | |
// compare if its a checked checkbox or an input with something in it | |
if ((otherFieldElement.type === 'checkbox' && otherFieldElement.checked) | |
|| (otherFieldElement.type !== 'checkbox' && otherFieldElement.value)) { | |
// the other field is checked or provided, so this field is required, and | |
// thus valid only if it has a value | |
return Boolean(value); | |
} | |
// the other field does not match the value, so this element is not | |
// required, and thus always valid | |
return true; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SomeModel | |
{ | |
public bool SendMeMail { get; set; } | |
[RequiredIf("SendMeMail")] | |
public string EmailAddress { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment