How to get resource strings in strongly typed way in asp.net core?

  1. Create a Resource file (.resx) with your translations. For example if you're localizing AboutController that would be something like AboutController.String.resx.

  2. Enable code generation for your resource file by changing Access Modifier from "No code generation" to "Public" or "Internal" while on edit resource screen. On save this will create a .Designer.cs class for your resource file. It will contain a static property for each key in the resource file. Don't modify the generated class manually. It'll be regenerated automatically after each modification of the .resx.

  1. Use the generated designer class in your controller to get translated text (no need for string localizer in that case):

     [HttpGet]
     public string Get()
     {
         return AboutController_Strings.AboutTitle;
     }
    

    This will work with using static trick as well:

     using static Localization.StarterWeb.AboutController_Strings;
    
     //(...)
    
     [HttpGet]
     public string Get()
     {
         return AboutTitle;
     }
    

    Alternatively you can use it with ASP's localizers. This adds no value at in that particular case but can be useful with the IHtmlLocalizer as it'll html-escape the values for you.

     [HttpGet]
     public string Get()
     {
         return _localizer[nameof(AboutTitle)];
     }
    

Why is this better than the accepted answer? This way you do not need to manually create and maintain all of LocalizationKeys-like classes with number of const strings inside. (In bigger projects there will be hundreds or thousands of them!) The generated .Designer.cs class will contain all keys from your resource file. Nothing more. Nothing less. If you delete something from the resource fill it will be deleted from the generated code and produce compilation errors in your code wherever the deleted property was used. If you add something to the resource file it will automatically generate a new property on save of the resource file which will appear in code-completion.

This is a more traditional approach, the way it was originally done with with for example WinForms. In the Microsoft's documentation for localizing ASP.NET Core apps there a brief explanation why they added a new way using IStringLocalizer: hardcoding translation string makes your workflow faster. There's no need to maintain additional things until needed.

For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an app. Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.


If you're trying to avoid using a hardcoded string (key) to lookup the localization conversion you could create a LocalizationKeys class that contains the lookup keys for you. You could then leverage the C# 6 nameof operator. This would help alleviate the concern of "magic strings".

public static class LocalizationKeys
{
    public const string AboutTitle = nameof(AboutTitle); // Note: this is "AboutTitle"

    // ... other keys here
}

Then you could consume it wherever. One of the benefits are that since this is a member of the class, if the key changes you can use common refactoring tools to safely replace all the references to it rather than trying to do a global string replace on the "magic string". Another benefit is you'd get to use intellisense when accessing the class. I suppose one could consider this "strongly typed".

You'd consume it as such:

[Route("api/[controller]")]
public class AboutController : Controller
{
    private readonly IStringLocalizer<AboutController> _localizer;

    public AboutController(IStringLocalizer<AboutController> localizer)
    {
        _localizer = localizer;
    }

    [HttpGet]
    public string Get()
    {
        return _localizer[LocalizationKeys.AboutTitle];
    }
}

If you really want to get fancy with C# 6 you can also utilize a static using. This will allow you to reference the members of the type you specify. Finally, for simple "single line" returns, we can make them expression bodies. For example:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using static Localization.StarterWeb.LocalizationKeys; // Note: static keyword

namespace Localization.StarterWeb.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get() => _localizer[AboutTitle]; // Note: omission of qualifier
    }
}

Just for people looking at this today: I don't known, when Microsoft added this, but in .Net 5.0 you could simply do this to your Configure function:

app.UseRequestLocalization(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en"),
                new CultureInfo("de")
            };
            options.DefaultRequestCulture = new RequestCulture("en", "en");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });

and just use the normal resource files with the static generated classes without the need for IStringLocalizer or anything like that. I don't know, if you can simply use them in razorpages or anything like that, but it works as expected in a normal "webapi" project.


Comments

  1. Jameson

    • 2020/12/15

    How to get resource strings in strongly typed way in asp.net core

  2. Cook

    • 2020/7/13

    using static Localization.StarterWeb.AboutController_Strings; //() [HttpGet] public string Get() { return AboutTitle; } Alternatively you can use it with ASP's localizers. This adds no value at in that particular case but can be useful with the IHtmlLocalizer as it'll html-escape the values for you.

  3. Jacob

    • 2019/8/17

    Create a Resource file (. resx) with your translations.

  4. Turner

    • 2017/1/11

    From this SO question I see that it is possible to get the controller and action from ActionExecutingContext, but as strings. Is there a chance to compare that in typed way like comparing to the controller class (e.g. HomeController) or the actual controller is not instanced at that point?

  5. Mohamed

    • 2021/2/8

    Enable code generation for your resource file by changing Access Modifier from "No code generation" to "Public" or "Internal" while on edit resource screen. On save this will create a .

  6. Isaiah

    • 2015/12/16

    ASP.NET Core API with localized strings. 0. We have an ASP.NET Core API. There are no views as again this is a simple API. We have strings in resource files (by culture) and we want each user to get the correct resource (in each API request we have a language name parameter). Also we like to use strongly typed resources in the code.

  7. Zander

    • 2020/2/25

    Create a Resource file (.resx) with your translations. For example if you're localizing AboutController that would be something like 

  8. Marcus

    • 2016/8/17

    The new way of using configuration settings in ASP.NET Core MVC is via an appsettings.json file within your Web project. No more XML configuration files (even though you still can), instead, a modern implementation of a multi-environment configuration system is built into ASP.NET Core MVC.

  9. Morales

    • 2015/10/22

    If you've used WinForms application you might envy the fact that there you get strongly typed resources automatically for your RESX files 

  10. Brody

    • 2016/6/29

    Before the introduction of ASP.NET 4.5, we would bind the data to the ASP.NET controls using the DataSource property and bind the data using the "Eval(expression)" function. Eval evaluates the expression and displays the data in the display controls. ASP.NET 4.5 came up with a new feature called strongly typed data controls.

  11. Archer

    • 2016/2/26

    Please remember that you must have administrator privileges to install and register new Visual Studio .NET custom tools. There are two ways to register the 

  12. Zechariah

    • 2016/5/21

    The very first thing is to add two Global Resource files one for English and one for French with the following names. English - Resource.resx. French – Resource.fr.resx. As soon as you add the first Resource file you will get the following prompt from Visual Studio asking to create a folder named App_GlobalResources.

  13. Ian

    • 2015/12/25

    Strongly typed resource support is a compile-time feature that encapsulates access to resources by creating classes that contain a set of static, read-only ( 

  14. Banks

    • 2019/7/4

    Below is the easiest way I know to use strongly typed approach in asp.net core application. Lets start by creating a basic asp.net API application. Detailed steps can be found here. This should put appsettings.json file in the root project. ASP.Net core's configuration can automatically detect the presence of appsettings.json file if its with

  15. Lewis

    • 2016/12/3

    This code isn't as nice as the code shown earlier to access a named string from with a global resource using a strongly typed class. Local 

  16. Thomas

    • 2016/10/13

    There are several ways you can access a global resource in your HTML elements. The easiest way is to use strong type resources. <p><%=Resources.Strings.

  17. Santana

    • 2016/7/24

    NET Core through two main abstractions IStringLocalizer and That way, I can use the strongly typed Title property whenever I'm accessing 

Comments are closed.

Recent Posts