Basically for the backend you need to create a custom validation that can be used as a attribute over the field to validate.
This is an example of a validation that checks if "number is greater than another filed".
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class NumberGreaterThanAttribute : ValidationAttribute, IClientValidatable
{
string otherPropertyName;
public NumberGreaterThanAttribute(string otherPropertyName, string errorMessage)
: base(errorMessage)
{
this.otherPropertyName = otherPropertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
if (value == null)
return validationResult;
try
{
// Using reflection we can get a reference to the other date property, in this example the project start date
var otherPropertyInfo = validationContext.ObjectType.GetProperty(this.otherPropertyName);
object referenceProperty = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
if (referenceProperty == null)
return validationResult;
double referenceProperty_value = System.Convert.ToDouble(referenceProperty, null);
double currentField_value = System.Convert.ToDouble(value, null);
if (currentField_value <= referenceProperty_value)
{
validationResult = new ValidationResult(ErrorMessageString);
}
}
catch (Exception ex)
{
throw ex;
}
return validationResult;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
//string errorMessage = this.FormatErrorMessage(metadata.DisplayName);
string errorMessage = ErrorMessageString;
// The value we set here are needed by the jQuery adapter
ModelClientValidationRule numberGreaterThanRule = new ModelClientValidationRule();
numberGreaterThanRule.ErrorMessage = errorMessage;
numberGreaterThanRule.ValidationType = "numbergreaterthan"; // This is the name the jQuery adapter will use
//"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
numberGreaterThanRule.ValidationParameters.Add("otherpropertyname", otherPropertyName);
yield return numberGreaterThanRule;
}
}
REMEMBER: frontend validation is not automatically enabled, for custom/newly created validations. If you want to create the same validation rules for the frontend you'll need to create a new frontend custom validation. I generally use validate.js library for the frontend. Still, frontend validation is not strictly required (but I'd suggest to use it in any case) if you don't mind pushing data back and forth from server to client, especially if data is small.
The ViewModel/Model will be received and parsed by modelstate when the backend receives the request(generally a POST). The model/viewmodel should be decorated on the fields that require the validation as so:
public Int64? AtomicQtyMultiplePurchaseMin { get; set; }
[NumberGreaterThanAttribute("AtomicQtyMultiplePurchaseMin", "Must be greater than min num. qty. of purchase")]
public Int64? AtomicQtyMultiplePurchaseMax { get; set; }
I generally place the custom validation classes in the following folder (but you can place it where you want in the project):
