'Using conditional statements while validating using attributes in MVC?
I am wondering if it is possible to use If statements when adding validation using attributes in MVC. Everything I have so far works out but there are certain values that are dependent on user input. For example:
Zip Validation:
If country is US, ensure ZIP is 5 digits long
If country is Canada, require data in “A1A 1A1” format
public class Customer
{
public int MasterContactID { get; set; }
[Required(ErrorMessage="Please enter company")]
public string Company { get; set; }
[Required(ErrorMessage = "Please enter a contact name")]
public string Contact { get; set; }
[Required(ErrorMessage = "Please enter an address")]
public string Address1 { get; set; }
public string Address2 { get; set; }
[Required(ErrorMessage = "Please enter a city")]
public string City { get; set; }
[Required(ErrorMessage = "Please enter State")]
public string State { get; set; }
[Required(ErrorMessage = "Please enter Country")]
public string Country { get; set; }
[Required(ErrorMessage = "Please enter Zip")]
public string Zip { get; set; }
public string Zip4 { get; set; }
[Required(ErrorMessage = "Please enter an Email Address")]
[EmailAddress(ErrorMessage = "Please enter a valid Email Address")]
public string Email { get; set; }
[RegularExpression(@"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", ErrorMessage = "Please enter valid phone number (xxx-xxx-xxxx) ")]
public string Phone { get; set; }
[Required (ErrorMessage = "Please indicate whether ACTIVE or INACTIVE")]
public string CustStatus { get; set; }
public enum Status
{
ACTIVE,
INACTIVE
}
}
Apologies if this isn't the proper way to ask a question on here as this is the first question I ask. Thank you.
Solution 1:[1]
Solution 1: Custom ValidationAttribute
You can implement a custom ValidationAttribute that inherits ValidationAttribute.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public class ZipValidationAttribute : ValidationAttribute
{
private readonly string _dependsOn;
public ZipValidationAttribute(string dependsOn) : base()
{
_dependsOn = dependsOn;
}
public ZipValidationAttribute(string dependsOn, string errorMessage) : base(errorMessage)
{
_dependsOn = dependsOn;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
try
{
string input = (string)value;
if (String.IsNullOrEmpty(input))
return validationResult;
// Using reflection to get a reference to the other property
var countryPropertyInfo = validationContext.ObjectType.GetProperty(_dependsOn);
string countryPropertyValue = (string)countryPropertyInfo.GetValue(validationContext.ObjectInstance, null);
switch (countryPropertyValue)
{
case "US":
if (input.Length != 5)
{
validationResult = new ValidationResult("When select country: US, Zip must be with 5 characters.");
}
break;
case "Canada":
Regex r = new Regex(@"^[a-zA-Z]\d[a-zA-Z]\s\d[a-zA-Z]\d$");
if (!r.IsMatch(input))
{
validationResult = new ValidationResult("When select country: Canada, Zip must be in 'A1A 1A1' format.");
}
break;
}
}
catch (Exception ex)
{
throw ex;
}
return validationResult;
}
}
And apply [ZipValidation("Country")] attribute to Zip property. Pass "Country" as the custom validation will be depended on the Country property.
public class Customer
{
...
[Required(ErrorMessage = "Please enter Zip")]
[ZipValidation("Country")]
public string Zip { get; set; }
}
Solution 2: Implement IValidatableObject.
Customer class to implement IValidatableObject
public class Customer : IValidatableObject
{
...
[Required(ErrorMessage = "Please enter Country")]
public string Country { get; set; }
[Required(ErrorMessage = "Please enter Zip")]
public string Zip { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
switch (this.Country)
{
case "US":
if (this.Zip.Length != 5)
{
results.Add(new ValidationResult("When select country: US, Zip must be with 5 characters."));
}
break;
case "Canada":
Regex r = new Regex(@"^[a-zA-Z]\d[a-zA-Z]\s\d[a-zA-Z]\d$");
if (!r.IsMatch(this.Zip))
{
results.Add(new ValidationResult("When select country: Canada, Zip must be in 'A1A 1A1' format."));
}
break;
}
return results;
}
}
Solution 3: Perform the validation in Controller
Implement the validation in the controller method. And when it fails the validation, pass the error message to ModelState.Errors and return to View.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yong Shun |
