Search code examples
razorasp.net-coreasp.net-core-localization

How to use localization in Razor Class Library in Asp.Net Core


I have tried to create the Razor Class Library with Asp.Net Core in following project structure:

enter image description here

I have used in my web application these settings for localization in Startup class:

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                    .AddViewLocalization(
                        LanguageViewLocationExpanderFormat.Suffix,
                        opts => { opts.ResourcesPath = "Resources"; })
                    .AddDataAnnotationsLocalization();

                services.Configure<RequestLocalizationOptions>(
                    opts =>
                    {
                        var supportedCultures = new[]
                        {
                            new CultureInfo("en-US"),
                            new CultureInfo("en")
                        };

                        opts.DefaultRequestCulture = new RequestCulture("en");
                        opts.SupportedCultures = supportedCultures;
                        opts.SupportedUICultures = supportedCultures;
                    });

....

var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
            app.UseRequestLocalization(options.Value);

In Index.cshtml:

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer


<h1>@Localizer["Title"]</h1>

Unfortunately, the result is only string "Title". I can't load these resx files from Razor Class Library.

How can I use the localization in Razor Class Library like above?

UPDATE: This is very similiar use case - https://github.com/aspnet/Localization/issues/328 - that provides some example.


Solution

  • You appear to have forgotten to configure localization correctly using AddLocalization

    Using details provided from documentation

    Reference Globalization and localization in ASP.NET Core

    Configure localization

    Localization is configured in the ConfigureServices method:

    services.AddLocalization(options => options.ResourcesPath = "Resources"); //<<< This is required
    
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
        .AddDataAnnotationsLocalization();
        
    

    AddLocalization Adds the localization services to the services container. The code above also sets the resources path to "Resources".

    AddViewLocalization Adds support for localized view files.

    AddDataAnnotationsLocalization Adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

    Localization middleware

    The current culture on a request is set in the localization Middleware. The localization middleware is enabled in the Configure method. The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).

    var supportedCultures = new[] {
        new CultureInfo("en-US"),
        new CultureInfo("en")
    };
    
    app.UseRequestLocalization(new RequestLocalizationOptions{
        DefaultRequestCulture = new RequestCulture("en"),
        // Formatting numbers, dates, etc.
        SupportedCultures = supportedCultures,
        // UI strings that we have localized.
        SupportedUICultures = supportedCultures;
    });
    
    //...other middleware
    
    app.UseMvcWithDefaultRoute();
    

    The path to the resource file shown in the example image follows the path naming convention given that you are using the ResourcesPath option which was set to "Resources". This should allow the view to find the resource file in the relative path to the "Resources" folder.

    An alternative is to not use the ResourcesPath option, and place the .resx file in the same folder as the view, following the naming convention of course.

    Base on additional details provided it was indicated that the UI project would be packaged as a nuget package.

    Then have the resources files packaged into the nuget package and have them unpacked to the resources folder of the target project when when installed.

    The resources need to be in the site root to be available to the view, so you then need to reference all the files in your .nuspec:

    <?xml version="1.0"?>
    <package>
        <metadata>...
        </metadata>
        <files>
            <!-- Add all resource files -->
            <file src="Resources\**\*.resx" target="content\Resources" />
        </files>
    </package>
    

    Reference Creating NuGet packages