I may be not doing the correct configurations in the Startup.cs
file. I have created a demo application to make it working, but after trying various things it is not working. The demo repository is available at following link
https://github.com/gurpreet42/MyAppV3
Configurations of startup.cs files are
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<LocService>();
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("nl")
};
options.DefaultRequestCulture = new RequestCulture("en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
services.AddMvc()
.AddViewLocalization()
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
{
var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
return factory.Create("SharedResource", assemblyName.Name);
};
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
// Localisation
var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseSession();
app.UseSession();
app.UseCookiePolicy();
}
The code in the LocService
class is
public class LocService
{
private readonly IStringLocalizer _localizer;
public LocService(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create("SharedResource", assemblyName.Name);
}
public LocalizedString GetLocalizedHtmlString(string key)
{
var value= _localizer[key];
return value;
}
}
Now on our controller, we can access the localized string as
localizerService.GetLocalizedHtmlString("my_string")
Under the "Resources" folder we have following files present
SharedResource.cs
SharedResource.en-US.resx
SharedResource.nl.resx
Please suggest where the configurations are wrong or do I need to add some extra package?
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With