How do you set different MaxLength attributes on a class consumed by many classes where the MaxLength can be different for each consuming class.
In my case, I am using Entity Framework and MVC. I have a complex type in my Entity Data Model for BilingualStrings which consist of an English and a French string. I have many entities that have a bilingual string which uses the complex type to map the English and French to the correct database table/column. So each table has two columns, but the entity has one property of type BilingualString. The field length is always the same for each English or French in a single table, but can be different for each table.
Here is a simplified example of what I am trying to achieve:
public partial class BilingualString
{
//[MaxLength(40)] Cannot put MaxLength here because it would apply to all instances of BilingualString
public string English { get; set; }
public string French { get; set; }
}
public class ClassWithShortDescription
{
//[MaxLength(20)] Cannot put MaxLength here because it does not makes sense. It needs to be on each English and French properties.
public BilingualString Description { get; set; }
}
public class ClassWithLongDescription
{
//[MaxLength(200)] Cannot put MaxLength here because it does not makes sense. It needs to be on each English and French properties.
public BilingualString Description { get; set; }
}
After some reading and lots of googling, I concluded that the underlying issue is that the meta data set by data attributes is static. Therefore the nested class properties cannot have different meta data even if consumed by different classes. The solution is to put the meta data on the property of the consuming class. Create a custom maxlength attribute that is applied to the property of type BilingualString.
Custom MaxLength Attribute for BilingualString public class MaxLengthBilingualStringAttribute : MaxLengthAttribute { public MaxLengthBilingualStringAttribute(int length) : base(length) { }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
BilingualString bilingualString = new BilingualString();
if (value.GetType() == typeof(EdmBilingualStringVarCharSingleLine))
{
var bs = value as EdmBilingualStringVarCharSingleLine;
bilingualString.English = bs.English;
bilingualString.French = bs.French;
}
else
return new ValidationResult("MaxLengthBilingualString Attribute does cannot be used with this type.");
if (bilingualString.English != null && bilingualString.English.Length > this.Length )
return new ValidationResult(string.Format("The maximum field length of {0} has been exceed for {1} English.", this.Length, validationContext.DisplayName));
if (bilingualString.French != null && bilingualString.French.Length > this.Length)
return new ValidationResult(string.Format("The maximum field length of {0} has been exceed for {1} French.", this.Length, validationContext.DisplayName));
return ValidationResult.Success;
}
}
Example Implementation:
public partial class BilingualString
{
public string English { get; set; }
public string French { get; set; }
}
public class ClassWithShortDescription
{
[MaxLengthBilingualString(20)]
public BilingualString Description { get; set; }
}
public class ClassWithLongDescription
{
[MaxLengthBilingualString(200)]
public BilingualString Description { get; set; }
}