Jenan
Jenan

Reputation: 3320

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.

Upvotes: 5

Views: 6128

Answers (2)

Terry
Terry

Reputation: 1992

I haven't tried the accepted answer and based on the comments, it seems the OP didn't get it to work. I implemented a pattern similar to the View/Page locator pattern that MVC/Razor Pages uses namely, that resources can be provided in a RCL or separate assembly and use ViewLocalizer and it'll just find the matching resource string from the highest precedence resource. You can read my implementation and see if it might work for you.

https://terryaney.wordpress.com/2021/01/04/migrating-to-net-core-overridable-localization-in-razor-class-libraries/

Upvotes: 2

Nkosi
Nkosi

Reputation: 247098

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

Upvotes: 1

Related Questions