MaximumWeightAttribute custom attribute - usage [MaximumWeight("PropertyName", "PropertyValue", MaxWeightInt)]
public class MaximumWeightAttribute : ValidationAttribute, IClientValidatable { | |
private const string ERRORMSG = "Weight must not exceed {0} lbs."; | |
public string DependentProperty { get; set; } | |
public string DependentValue { get; set; } | |
public int MaximumWeight { get; set; } | |
public MaximumWeightAttribute(string dependentProperty, string dependentValue, int maximumWeight) { | |
this.DependentProperty = dependentProperty; | |
this.DependentValue = dependentValue; | |
this.MaximumWeight = maximumWeight; | |
} | |
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { | |
var rule = new ModelClientValidationRule() { | |
ErrorMessage = String.Format(ERRORMSG, this.MaximumWeight), | |
ValidationType = "maximumweight", | |
}; | |
string depProp = BuildDependentPropertyId(metadata, context as ViewContext); | |
rule.ValidationParameters.Add("dependentproperty", depProp); | |
rule.ValidationParameters.Add("dependentvalue", this.DependentValue); | |
rule.ValidationParameters.Add("weightvalue", this.MaximumWeight); | |
yield return rule; | |
} | |
protected override ValidationResult IsValid(object value, ValidationContext validationContext) { | |
// get a reference to the property this validation depends upon | |
var containerType = validationContext.ObjectInstance.GetType(); | |
var field = containerType.GetProperty(this.DependentProperty); | |
if (field != null) { | |
// get the value of the dependent property | |
var dependentvalue = field.GetValue(validationContext.ObjectInstance, null); | |
var weight = containerType.GetProperty(validationContext.DisplayName); | |
int weightvalue = (int)weight.GetValue(validationContext.ObjectInstance, null); | |
// compare the value against the target value | |
if (dependentvalue == this.DependentValue && weightvalue > this.MaximumWeight) { | |
// validation failed - return an error | |
return new ValidationResult(String.Format(ERRORMSG, this.MaximumWeight)); | |
} | |
} | |
return ValidationResult.Success; | |
} | |
private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext) { | |
// build the ID of the property | |
string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(this.DependentProperty); | |
// unfortunately this will have the name of the current field appended to the beginning, | |
// because the TemplateInfo's context has had this fieldname appended to it. Instead, we | |
// want to get the context as though it was one level higher (i.e. outside the current property, | |
// which is the containing object (our Person), and hence the same level as the dependent property. | |
var thisField = metadata.PropertyName + "_"; | |
if (depProp.StartsWith(thisField)) | |
// strip it off again | |
depProp = depProp.Substring(thisField.Length); | |
return depProp; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment