23

Adding a resource file to App_GlobalResources with a PropertyValueRequired key and changing DefaultModelBinder.ResourceClassKey to the file name has no effect on MVC 4. The string The {0} field is required is never changed. I don't want to set the resource class type and key on every required field. Am I missing something?

Edit:

I've made a small modification on Darin Dimitrov's code to keep Required customizations working:

public class MyRequiredAttributeAdapter : RequiredAttributeAdapter
{
    public MyRequiredAttributeAdapter(
        ModelMetadata metadata,
        ControllerContext context,
        RequiredAttribute attribute
    )
        : base(metadata, context, attribute)
    {
        if (attribute.ErrorMessageResourceType == null)
        {
            attribute.ErrorMessageResourceType = typeof(Messages);
        }
        if (attribute.ErrorMessageResourceName == null)
        {
            attribute.ErrorMessageResourceName = "PropertyValueRequired";
        }
    }
}
Eduardo
  • 5,645
  • 4
  • 49
  • 57

1 Answers1

41

This is not specific to ASP.NET MVC 4. It was the same in ASP.NET MVC 3. You cannot set the required message using DefaultModelBinder.ResourceClassKey, only the PropertyValueInvalid.

One way to achieve what you are looking for is to define a custom RequiredAttributeAdapter:

public class MyRequiredAttributeAdapter : RequiredAttributeAdapter
{
    public MyRequiredAttributeAdapter(
        ModelMetadata metadata,
        ControllerContext context,
        RequiredAttribute attribute
    ) : base(metadata, context, attribute)
    {
        attribute.ErrorMessageResourceType = typeof(Messages);
        attribute.ErrorMessageResourceName = "PropertyValueRequired";
    }
}

that you will register in Application_Start:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(RequiredAttribute),
    typeof(MyRequiredAttributeAdapter)
);

Now when a non-nullable field is not assigned a value, the error message will come from Messages.PropertyValueRequired where Messages.resx must be defined inside App_GlobalResources.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Perfect! I did a lot of research and found nothing similar. Thank you very much. – Eduardo Sep 22 '12 at 23:54
  • Is it possible to do something similar for the type validation, e.g. for dates? – Rowan Jun 23 '13 at 10:39
  • 1
    We researched why you need an adapter for this: the entry GlobalResources.PropertyValueRequired is only used for non-nullable types which are not marked as "Required". The "real" Required message can only be changed using this adapter solution. – D.R. Sep 24 '13 at 14:57
  • There exist `DataTypeAttributeAdapter` and `CompareAttributeAdapter` but unlike `RequiredAttributeAdapter` they are internal. What the hell? – UserControl Feb 14 '14 at 07:00
  • 2
    Great answer! I will add that resx file doesn't have to be located in App_GlobalResources folder. It doesn't have to be located in the same project at all. – adams Aug 25 '14 at 08:00
  • The derived RequiredAttributeAdapter does not seem to be called on custom datatypes, thus the metadata in the EditorTemplate does only contain the default error message. Does anyone know a solution for this? – Alex Sep 30 '14 at 05:40