I've based myself upon this question to create a custom validation attribute with asp.net mvc3 and jquery validate :
I've updated it to work with a group of string properties instead of bool. Which works fine. But my issue comes when I use it with custom ErrorMessage the custom message is not displayed. And I cannot figure out why.
[RequiredOneFromGroup("PhoneGroup",
ErrorMessageResourceName = "PhoneGroup",
ErrorMessageResourceType = typeof(WizardStrings))]
public String Mobile { get; set; }
[RequiredOneFromGroup("PhoneGroup",
ErrorMessageResourceName = "PhoneGroup",
ErrorMessageResourceType = typeof(WizardStrings))]
public String Phone { get; set; }
Here's the custom validation attribute :
[AttributeUsage(AttributeTargets.Property)]
public class RequiredOneFromGroup : ValidationAttribute, IClientValidatable
{
public RequiredOneFromGroup(string groupName)
{
ErrorMessage = string.Format("You must select at least one value from group \"{0}\"", groupName);
GroupName = groupName;
}
public string GroupName { get; private set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
foreach (var property in GetGroupProperties(validationContext.ObjectType))
{
var propertyValue = (string)property.GetValue(validationContext.ObjectInstance, null);
if ( ! string.IsNullOrWhiteSpace(propertyValue))
{
// at least one property is true in this group => the model is valid
return null;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
private IEnumerable<PropertyInfo> GetGroupProperties(Type type)
{
return
from property in type.GetProperties()
where property.PropertyType == typeof(string)
let attributes = property.GetCustomAttributes(typeof(RequiredOneFromGroup), false).OfType<RequiredOneFromGroup>()
where attributes.Count() > 0
from attribute in attributes
where attribute.GroupName == GroupName
select property;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var groupProperties = GetGroupProperties(metadata.ContainerType).Select(p => p.Name);
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage
};
rule.ValidationType = string.Format("group", GroupName.ToLower());
rule.ValidationParameters["propertynames"] = string.Join(",", groupProperties);
yield return rule;
}
}
I've tried to remove the manual setting of the ErrorMessage but then I would get an empty error message. How can I retrieve the value of ErrorMessageResourceName that I specify in the Named Parameters of the model ? And how can I set it so the custom validation attribute display it ?