I created an inherited attribute like this in ASP.NET MVC3:
public sealed class RequiredFromResourceAttribute : RequiredAttribute
{
public RequiredFromResourceAttribute(string errorResourceName, string errorResourceTypeName)
{
this.ErrorMessageResourceName = errorResourceName;
this.ErrorMessageResourceType = Type.GetType(errorResourceTypeName);
}
}
And use it like this:
[RequiredFromResource("Title", "Resources.Resource, MyProject.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")]
public string Title { get; set; }
It didn't work and the MVC ignored it. Then I create a simpler class which just inherited from RequiredAttribute like this:
public class MyRequiredAttribute : RequiredAttribute
{
}
I use it like that I said. But it didn't work again.
Although, all these ways work on "DisplayNameAtrribute" perfectly.
What is the problem?
You can fix this by adding the following code in Global.asax: (found the answer here)
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredLocalizableAttribute), typeof(RequiredAttributeAdapter));
Alternatively, using marcind's solution, I found that the constructor for ModelClientValidationRequiredRule
requires an error message. Here is an updated version that includes the display name for the field:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
string msg = FormatErrorMessage(metadata.GetDisplayName());
yield return new ModelClientValidationRequiredRule(msg);
}
It's only client-side validation that does not work with inherited attributes. The reason for that is that MVC uses strict type equality when mapping server-side attributes to client validation behaviors.
To work around this you will need your custom attribute to implement IClientValidatable
:
public class MyRequiredAttribute : IClientValidatable {
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
yield return new ModelClientValidationRequiredRule();
}
}