asp.netasp.net-mvc-4localizationapp-globalresources

Localization in ASP.NET MVC 4 using App_GlobalResources


I am trying to accomplish two things:

  1. Localize the “built-in” error messages for “FieldMustBeDate” and "FieldMustBeNumeric".
  2. Localize some of the other error messages you would encounter, for example, "PropertyValueRequired".

By using http://forums.asp.net/t/1862672.aspx/1 for problem 1 and MVC 4 ignores DefaultModelBinder.ResourceClassKey for problem 2 I have managed to get both working locally.

However as soon as I publish to a website, the “built-in” error messages defaults back to English while the other error messages stay localized.

I have read several places that using the App_GlobalResources should be avoided, however I am unable to accomplish problem 1 without using this.

I have created a .resx file with the name “WebResources.resx”, set the Build Action to “Embedded”, set the Copy to Output Directory to “Do no Copy”, set the Custom Tool to “PublicResXFileCodeGenerator” and set the Custom Tool Namespace to “Resources”. The Project itself is set to only Publish files that are needed.

My Global.asax.cs contains the following (relevant) code:

  ClientDataTypeModelValidatorProvider.ResourceClassKey = "WebResources";  
  DataAnnotationsModelValidatorProvider.RegisterAdapter(
  typeof(RequiredAttribute),
  typeof(MyRequiredAttributeAdapter));

And the class MyRequiredAttributeAdapter contains the following code:

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

This is working locally however does anyone have any idea on how to get the "built in" messages to work after this is published?

Thank you for your help!

Best regards, Andreas


Solution

  • I figured this one out myself. If you are trying to accomplish the above you must separate the localized error messages.

    Create a *.resx file for the other error messages fx "PropertyValueRequired" and set the Build Action to “Embedded”, set the Copy to Output Directory to “Do no Copy”, set the Custom Tool to “PublicResXFileCodeGenerator” and set the Custom Tool Namespace to “Resources”.

    In my case I have moved "PropertyValueRequired" to a file called LocalDanish.resx (still in the App_GlobalResources folder) and changed the line in my "MyRequiredAttributeAdapter" from

    attribute.ErrorMessageResourceType = typeof(Resources.WebResources);
    

    to

    attribute.ErrorMessageResourceType = typeof(Resources.LocalDanish);
    

    In order to get the "built in" error messages to work, you must create two *.resx files. I have created WebResources.resx and WebResources.da.resx. Do NOT change anything, leave the settings on them on default (Build Action to "Content", etc.). I guess the website automatically looks for the *.da.resx files in my case because I have set the globalization in my WebConfig:

    <globalization uiCulture="da-DK" culture="da-DK"/>
    

    Hope this helps anybody.

    Best regards, Andreas