Note that there is a difference between CurrentCulture and CurrentUICulture in dotnet. Same thing in the CMS. Looking at your controller name, I assume you're interested in CurrentUICulture.
Since you're not using our routing, you're responsible for settings the correct values for these static properties. You can update these by calling IUpdateContentLanguage.ResolveCulture(string culture)
and/or IUpdateUserInterfaceLanguage.ResolveCulture(string culture)
depending on if you just want to load content in correct language or just load other translated resources.
You can probably just update the cultures on the current thread too (Thread.CurrentThread.CurrentUICulture
and Thread.CurrentThread.CurrentCulture
), but I would recommend using the above methods instead.
You also have the option to be explicit in each method and provide the language manually, e.g. IContentLoader accepts a CultureInfo object.
How do I resolve IUpdateContentLanguage.ResolveCulture(string culture)?
It doesn't exist as a DI?
I think that would be over-complicated. I would recommend binding a parameter to the Accept-Language header. Or just use attribute routing:
private readonly IUpdateUserInterfaceLanguage updateUserInterfaceLanguage;
private readonly IUpdateContentLanguage updateContentLanguage;
// Resolve interfaces with constructor injection.
[Route("{language}/api/[controller]/[action]")]
[HttpGet]
public IActionResult Translate(string language)
{
updateUserInterfaceLanguage.ResolveCulture(language)
updateContentLanguage.ResolveCulture(language)
}
You probably want to add this in a custom binder and/or filter.
private readonly IUpdateUserInterfaceLanguage updateUserInterfaceLanguage; is a later feature than 12.6.0? :)
It doesn't exist for me. Nuget package?
These interfaces exists in the EPiServer.Cms.AspNetCore package. They have existed as long as I can remember, but in earlier versions they were in a different package.
@Johan, I find it difficult to handle cultures for non-content requests. ContentLanguageImplementation is internal and can't be overridden. The method LanguagePreferenceList in ContentLanguageImplementation is also very difficult to affect. Accept Language is ONLY used if UseBrowserLanguagePreferences is true, which is not optimal. For content requests, I don't want to use UseBrowserLanguagePreferences but for API requests I do want to use the Accept Language header. Or some other header, but I can't because I can't override the behaviour. I could not use ContentLanguageImplementation at all but then I won't be able to take part of DetermineCulture, which is sad because it's a good way to determine the most suitable culture to use given the preferences.
Please provide a way to change the behaviour. Simply giving us a way to affect LanguagePreferenceList would probably be enough.
What is the best practice in EPiServer for fetching the language context for an API controller?
In the controller
defaults to the master language - I'm guessing it's because the route does not include a language variable.
I've added UseRequestLocalization In Startup.cs but that enables 'CultureInfo.CurrentUICulture' to be correct - LanguageSelector.AutoDetect() is still on a master language.
@Johan, do you know if this is expected?