You can implement an attribute that does a custom validation in the same way as Required
, but only when the condition is satisfied, and use this attribute instead of Required
.
In this attribute implement the IClientValidatable
interface to be able to validate the client, when using non-obstructive validation, and implement a validation implementation with javascript.
An example is in this SOEN response:
I have adapted the response attribute presented above to have non-obstructive validation on the client:
public class RequiredIfAttribute : RequiredAttribute, IClientValidatable
{
private String PropertyName { get; set; }
private Object Comparand { get; set; }
public RequiredIfAttribute(String propertyName, Object comparand)
{
PropertyName = propertyName;
Comparand = comparand;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var instance = context.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue.ToString() == Comparand.ToString())
{
var result = base.IsValid(value, context);
return result;
}
return ValidationResult.Success;
}
IEnumerable<ModelClientValidationRule> IClientValidatable.GetClientValidationRules(
ModelMetadata metadata,
ControllerContext context)
{
var requiredIfRule = new ModelClientValidationRule();
requiredIfRule.ErrorMessage = this.ErrorMessageString;
requiredIfRule.ValidationType = "requiredif";
requiredIfRule.ValidationParameters.Add("propertyname", this.PropertyName);
requiredIfRule.ValidationParameters.Add("comparand", this.Comparand);
yield return requiredIfRule;
}
}
Create a javascript file, and include it in the page with the field to be validated:
$.validator.addMethod("requiredif", function (value, element, params) {
return $(params.propertyname).val() == params.comparand
? value != null && value != "" && value != undefined
: true;
});
$.validator.unobtrusive.adapters.add(
"requiredif",
["propertyname", "comparand"],
function (options) {
options.rules["propertyname"] = "#" + options.params.propertyname;
options.rules["comparand"] = options.params.comparand;
options.messages["requiredif"] = options.message;
});
And use it like this:
public class Trabalhador
{
[Required(ErrorMessage = "*")]
public int Id { get; set; }
[Required(ErrorMessage = "*")]
public String Nome { get; set; }
public String Aposentado { get; set; }
[RequiredIf("Aposentado", "S")]
public DateTime DataAposentadoria { get; set; }
}
Reference:
I could not determine the authorship of the RequiredIf
attribute ... searching Google for RequiredIfAttribute RequiredAttribute
returns numerous sources where this code is used. I'll search more, and if you find, I'll reference here. If someone finds the author, please feel free to edit the answer, or make a comment.