Created
October 22, 2011 19:29
-
-
Save timhobbs/1306396 to your computer and use it in GitHub Desktop.
MaximumWeightAttribute custom attribute - usage [MaximumWeight("PropertyName", "PropertyValue", MaxWeightInt)]
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 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