Search code examples
c#code-generationriderresx

Are each variations of a .resx file supposed to generate their own Designer.cs file?


I haven't been able to find much about how .Designer.cs files work in relations to .resx files in the official docs, and Googling for this kind of situation hasn't resulted in any useful information.


The project I'm currently working on needs to support multiple languages. As such, it has localization files:

  • Localization.resx
  • Localization.en.resx
  • Validation.resx
  • Validation.en.resx

Note: English isn't the default language.

I noticed that, along with the .resx files, we have some Designer.cs files. Specifically, we have the following ones:

  • Localization.Designer.cs
  • Localization.en.Designer.cs
  • Validation.Designer.cs

For some reason, Validation.en.resx does not have a corresponding .en.Designer.cs file.

If we make modifications to the .en.resx file, a designer file isn't generated for it. Those changes still work, though. Going on our site and setting the culture to English shows the English values. Looking at our Git status, there doesn't appear to be an .en.Designer.cs file somewhere else, and it isn't ignored by our .gitignore file.

To generate a Validation.en.Designer.cs file, I've tried:

  • Disabling code generation and re-enabling it as public
  • Using VS2022 with the "Run Custom Tool" action
  • Using Rider with the "Generate Resources" action
  • Creating blank .resx/.en.resx files and manually move the values inside of it
  • Updating the .csproj file manually to make sure it has the same ResX code as the other files

The only thing that's worked was to create an empty Validator.en.Designer.cs file, which instantly got populated with the correct values.

However, when team members make changes to the .en.resx file, the .en.Designer file isn't updated, even though their changes work when compiling/running the app. Changes to the default .resx files do result in changes to the .Designer.cs file, though.

So are we supposed to have an .en.Designer.cs file alongside our .en.resx file? Or is the default .Designer.cs file supposed to handle picking the correct .resx source based on local and we just have extra files in our project?


Solution

  • The short answer is, no, there is no Designer file for each localized resource file.

    The C# file does not actually hold the Value part of the resx file. It instead generates code to look up values in the resource files, this includes code for culture-dependent lookups as well. You can see this in the Designer file generated by the main resx file, there is a section of the C# code that says (reformatted for brevity):

    public static global::System.Globalization.CultureInfo Culture {
        get { return resourceCulture; }
        set { resourceCulture = value; }
    }
    

    This means that there is built-in support for localization, so when you set your culture:

    Resources.Validation.Culture = new CultureInfo("en");
    

    ...then reference the localized string later (using Greeting as an example):

    Console.WriteLine(Resources.Validation.Greeting);
    

    ...it will automatically select the proper resource. If no string is found, it will default to the main resx file.

    Example

    Let's say you have three resource files:

    • Main one: Validation.resx, contains (Anatid, Duck-translation here)
    • English: Validation.en.resx, contains (Anatid, Duck)
    • Japanese: Validation.ja-JP.resx, contains (Anatid, カモ)

    To use them:

    foreach (string loc in new[] { "en", "ja-JP", "sr-Cyrl-RS" })
    {
        Resources.Validation.Culture = new CultureInfo(loc);
        Console.WriteLine(Resources.Validation.Anatid);
    }
    /* Outputs:
    Duck
    カモ (Or ??. `chcp 932` if you really want to see katakana. Point is, it looks up the value.)
    Duck-translation here
    */
    

    For additional functionality, you can follow directions listed here, but it may be more than you need to do.