ASP.NET Core 3.1 : Shared Localization not working for version 3.1
There is no need to create the LocService you can use IStringLocalizer.
"Resources" folder structure
SharedResource.cs
SharedResource.en-US.resx
SharedResource.nl.resx
At the class SharedResource, do not add "Resources" in the namespace. Like MyAppV3.Resources. Please keep it just MyAppV3.
namespace MyAppV3
{
public class SharedResource
{
}
}
Add in your .csproj the following property
<PropertyGroup><EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention></PropertyGroup>
Add to startup.cs > ConfigureServices
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddScoped<IStringLocalizer, StringLocalizer<SharedResource>>();
services
.Configure<RequestLocalizationOptions>(options =>
{
var cultures = new[]
{
new CultureInfo("en"),
new CultureInfo("nl")
};
options.DefaultRequestCulture = new RequestCulture("en");
options.SupportedCultures = cultures;
options.SupportedUICultures = cultures;
});
Startup.cs > Configure
app.UseRequestLocalization(app.ApplicationServices
.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
Add to the controller the IStringLocalizer parameter.
public MyTestController(IStringLocalizer localizer)
{
this.localizer = localizer;
}
public IActionResult Get()
{
var value = this.localizer.GetString("RessourceName");
return this.Ok(value);
}
I had similar issue during upgrade from 2.2 to 3.1.
In 2.2 my setup was:
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc(config =>
{
... <omitted for brevity>
})
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
All resources where in "Resources" folder. SharedResources.cs had recommended namespace of the project:
// *************************
// DO NOT CHANGE NAMESPACE
// *************************
// ReSharper disable once CheckNamespace
namespace MyProject
{
// Dummy class to group shared resources
public class SharedResources
{
}
}
And View Localizations were based on the path e.g.
Resources
Pages
Error.en-US.resx
Error.ja-JP.resx
With 3.1, recommended setup was (with minimal changes):
services.AddLocalization();
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddControllersWithViews(config =>
{
... <omitted for brevity>
})
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
At this point SharedResources was working fine but IViewLocalizer and view localizations were not working.
I found two ways to fix it based on above suggestions and this article:
Opt out of the new naming convention, effectively going back to what was used in 2.2 by adding following to csproj file:
<PropertyGroup> <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention> </PropertyGroup>
And, adding options => options.ResourcesPath = "Resources"
back to services.AddLocalization()
.
Keep 3.1 setup and fix each view localization by adding dummy
.cs
file with namespace that is outside of resources folder, for example:Resources Pages Error.cs Error.en-US.resx Error.ja-JP.resx
Where Error.cs
is:
// *************************
// DO NOT CHANGE NAMESPACE
// *************************
// ReSharper disable once CheckNamespace
namespace MyProject.Pages
{
// Dummy class to group shared resources
public class Error
{
}
}
So if you have lots of View Localizations like me, #1 option would probably be better, as it is configuration change only, leaving all existing view localization as they were.
It turns out that in asp.net core 3.1, you need to place SharedResource.cs
out of Resources
folder(see this github issue)
If class SharedResource.cs
and SharedResource.*.resx
in same folder, the namespace will be error in compiled dll xxx.lang.dll
.
So, just delete original SharedResource.cs
create a new one under the project directly:
namespace MyAppV3
{
public class SharedResource
{
}
}
And read resource files to the Resources
folder.