ASP.NET Core/Razor Pages localize nested classes

You probably already know how to localize regular classes in ASP.NET Core web app. It’s rather easy, at least in terms of resource files. Sometimes however we use nested classes which requires special way of naming RESX files. As it turns out it is actually pretty easy to do.

If you want the answer right away, then here it is. You have to use + sign in the name of your resource file (like this: OuterClass+NestedClass.en.resx).

Localizing with resource files

Both Razor Pages and ASP.NET Core have built-in support for localization using resource files (RESX). Each resource file is basically an XML file. It contains keys (string to be localized), values (localized values) and optional comments. We access translations by using instances of IStringLocalizer (or IViewLocalizer for views) which lets us get localized strings by using indexers.

Resource files has to be named after class or view file. In addition it has to be put in directory structure which reflects namespace of localized file. Each language has to have its own RESX file, and the language code has to be a part of its file name. If you want to know more about it please refer to the official documentation located here.

REX file name for AccountController class and english culture.

Let me show you and example of how it works. We’ll start with a controller, notice the IStringLocalizer instance (_localizer)and how we can use it to access localization.

Localization in controller.

Now, take a look at the directory structure.

Localization directory structure.

Nested classes

Sometimes we want to create nested classes. There are various reasons you may want to do that. Personally, I do that for view models when I want to group chunk of common data or when I want to create a list of items because it’s used only at that place.

// Example nested class
public class ListViewModel
{
    public string SomeVariable { get; set; }

    public List<ListItem> Items { get; set; }

    public class ListItem
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }
}

So, how do we localize nested class in the example above? It pretty simple, we need to name RESX file in special way. Firstly, we include class name, then goes the plus sign and then goes the nested class name. That’s how reflection “sees” nested classes (outer class name, plus sign, inner class name).

RESX file name for nested class.