In a Controller action these variables:
var foo = Request.HttpContext.Features.Get<IRequestCultureFeature>()
.RequestCulture.Culture;
var bar = Thread.CurrentThread.CurrentCulture;
Both return "en"
. What's the difference between them and which is better to use in terms of determining the language of the user viewing the site??
According to the source code of RequestLocalizationMiddleware
public async Task Invoke(HttpContext context)
{
//..
context.Features.Set<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider));
SetCurrentThreadCulture(requestCulture);
await _next(context);
}
private static void SetCurrentThreadCulture(RequestCulture requestCulture)
{
CultureInfo.CurrentCulture = requestCulture.Culture;
CultureInfo.CurrentUICulture = requestCulture.UICulture;
}
the current request culture is set both for IRequestCultureFeature
and current CultureInfo
( CultureInfo.CurrentCulture
gets/sets Thread.CurrentThread.CurrentCulture
and therefore they are the same). So effectively there is no difference between these methods in terms of getting current culture.
The main difference is that IRequestCultureFeature
is bound to the current HttContext
(http request). And in my opinion when you are getting culture using IRequestCultureFeature
you are explicitly saying you need current request culture. And when you are using Thread.CurrentThread.CurrentCulture
it's not that clear that your intention is getting request culture. So I would prefer using IRequestCultureFeature
because of better readability. And one can say this is better for testing purposes as well.
But setting the culture, on the other hand, has different effect for each scenario. If you replace IRequestCultureFeature
by the following code
context.Features.Set<IRequestCultureFeature>(some request culture);
it will only replace the feature and won't affect anything else (afaik after researching some source code of the framework). But changing culture like this
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture; //namely this line has effect described bellow
will directly affect resource manager and fetching localizations. Browsing source code shows the dependency on CultureInfo.CurrentUICulture
protected string GetStringSafely(string name, CultureInfo culture)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
var keyCulture = culture ?? CultureInfo.CurrentUICulture;
//..
}
And simple tests confirm this
Res.culture1.resx
Value - First value
Res.culture2.resx
Value - Second value
//request culture is "culture1"
LocalizedString res = _stringLocalizer["Value"]; //"First value"
CultureInfo.CurrentUICulture = new CultureInfo("culture2");
LocalizedString res2 = _stringLocalizer["Value"]; //"Second value"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.