I made test attribute
[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
public class NonInheritedRequiredAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
return new ValidationResult((validationContext.DisplayName));
return null;
}
}
And viewModels
public class ViewModelA
{
[NonInheritedRequired]
public virtual string Property{ get; set; }
}
public class ViewModelB : ViewModelA
{
public override string Property{ get; set; }
}
Action method
[HttpPost]
public ActionResult Index(ViewModelB viewModel)
{
if (ModelState.IsValid)
{
return View("OtherView");
}
return View(viewModel);
}
ModelState always is not valid. On validating it uses validation of NonInheritedRequired despite it has Inherited = false. How can I solve this problem?
Thanks.
The Inherited
property isn't respected in MVC.
possible solutions:
Implement a custom ModelValidatorProvider
which will filter out non inheritable validation attributes.
Filter out non inheritable attributes by providing a custom TypeDescriptionProvider
Use MetadataType
attribute in your models. This is the easiest of all.
Sample
[MetadataType(typeof(ModelAMetadata))]
public class ModelA
{
public virtual string Property { get; set; }
}
public class ModelAMetadata
{
[Required]
public string Property { get; set; }
}
[MetadataType(typeof(ModelBMetadata))]
public class ModelB : ModelA
{
public override string Property { get; set; }
}
public class ModelBMetadata
{
//notice that there is no Required attribute here
public string Property { get; set; }
}
Most elegant solution is #1, but I suggest to redesign the Models instead.