Kinda confused here, super simple hello-world example of localization in ASP.Net Core 2.0. My About page is set up to render two localized strings:
- From the view (using
IViewLocalizer
) - From code (using
IStringLocalizer<HomeController>
via the controller)
The code in the controller refuses to get the loc string appropriately. This is not complicated, what obvious things am I missing?
About.cshtml
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
^ Note the two strings: "Message" will be localized from code using IStringLocalizer
(see HomeController below), and the @Localizer will use the IViewLocalizer
class.
HomeController.cs
public class HomeController : Controller
{
private readonly IStringLocalizer _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."];
return View();
}
}
Startup.cs (relevant parts)
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr-CH"),
};
options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Resources:
Views.Home.About.fr-CH.resx
^ with two values in it:
- "Use this area to provide additional information." = "Use this area... success for fr-CH!"
- "Your application description page." = "Your app descript... success for fr-CH!"
My Results:
localhost:56073/Home/About
^ This renders the strings as expected in en-US (default finds nothing, uses the strings actually hard coded)
localhost:56073/Home/About?culture=fr-CH
^ This renders ONLY the 2nd string: "Use this area... success for fr-CH!", which clearly means all the code wired up is working and finding the fr-CH.resx as expected.
BUT, the first string (set in code as ViewData["Message"]
) does NOT get the fr-CH version! It's like the IStringLocalizer<HomeController>
failed to realize there was a lang specified, or failed to find the fr-CH.resx that is clearly available.
Why???
Also BTW, I tried using the ShareResource example too (see link below), and passed in the factory to the HomeController ctor as IStringLocalizerFactory factory
, also with no love, still not getting the fr-CH resource. Sigh.
Other notes:
Using this as my primary reference: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization
Using VS 2017, latest updates, with ASP.Net Core 2.0