6

I’m trying to use the localization feature of ASP.Net Core in my Blazor app. I want to use IStringLocalizer so that I automatically detect the browser language to adapt to the user’s language. My solution consists of several projects and for cleanliness I wanted to gather the resource files in one and the same project (app.core) for all my other projects. you can see an example of my architecture :

solution app
|-- app.project1
|-- app.project2
|-- app.core
|   |-- Resources
|       |-- Localization
|           |-- project1
|           |-- project2
|           |-- web
|               |-- Pages
|                   |-- Index.en.resx
|                   |-- Index.fr.resx
|-- app.web
    |-- Pages
        |-- Index.razor

Resources related to the web project are located in the core project in the folder Resources > Localization > web.

I have looked at several existing questions before to orient myself, but I have not found a solution to my problem (or maybe I'm bad lol) :

When I put my resources in the same project, it works so it’s just that I can’t figure out how to do it when it’s in another project.

What I tried: In my web project in Configureservice I have .AddLocalization() and .Configure<RequestLocalizationOptions>(opt => ...) and in Configure I have app.UseRequestLocalization(). In my core project I created an AssemblyInfo.cs with [assembly: ResourceLocation("Resources/Localization/web")] and [assembly: RootNamespace("app")] (and other names like app.web, or app.core) but it doesn’t seem to work.

I don't like the solution to do dummy .cs for each .resx, I don't like to have useless classes.

I hope my problem is understandable and my English too. Thank you in advance for your answers, this is the first time I’ve come to ask for help here!

AspTester
  • 61
  • 2

1 Answers1

1

I've managed to do this recently. Most of the needed information has been gathered from here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1

Here's my solution structure:

solution app
|-- BlazorApp
|   |-- Localization
|       |-- MyTextsLocalizer.cs
|-- MyLib
|   |-- MyTexts.cs
|   |-- Localization
|       |-- MyTexts.resx
|       |-- MyTexts.cz.resx

MyLib

I wanted to have all the resource keys to be available as an enum. MyTexts is an enum that is being localized by with the resource files.

MyTexts.cs

namespace MyLib
{
    public enum MyTexts
    {
        HiThere
    }
}

Localization/MyTexts.resx

This file contains translation for the enum values. Only one translation in this example: key: HiThere, value: Hi there

Localization/MyTexts.cz.resx

This file contains translation for the enum values. Only one translation in this example: key: HiThere, value: Ahoj

BlazorApp

Localization/MyTextsLocalizer.cs

using Microsoft.Extensions.Localization;
using MyLib;
using MyLib.Localization;
using System.Reflection;

namespace BlazerApp.Localization
{
    public class MyTextsLocalizer
    {
        private readonly IStringLocalizer _localizer;

        public MyTextsLocalizer(IStringLocalizerFactory factory)
        {
            var type = typeof(MyTextsLoc);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(nameof(MyTextsLoc), assemblyName.Name);
        }

        public string Localize(MyTexts myTexts)
        {
            return _localizer.GetString(myTexts.ToString());
        }
    }
}

Startup.cs

I've added the following code to the ConfigureServices method.

Note that the options.ResourcesPath = "Localization" is important. The path has to be the path to where your resource files are located in the library. It doesn't work with an incorrect path.

services.AddLocalization(options =>
{
    options.ResourcesPath = "Localization";
});
var supportedCultures = new List<CultureInfo>
{
    new CultureInfo("en"),
    new CultureInfo("cz")
};
services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

services.AddSingleton<MyTextsLocalizer>();

Index.razor

The localizer is used in a razor component like this:

@page "/"

@using BlazerApp.Localization
@using MyLib

@inject MyTextsLocalizer loc

<h1>@loc.Localize(MyTexts.HiThere)</h1>

Michal Diviš
  • 2,008
  • 12
  • 19