Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between IRequestCultureFeature and CurrentCulture in Asp.Net Core?

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??

like image 698
Bob Tway Avatar asked Oct 30 '25 06:10

Bob Tway


1 Answers

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"
like image 138
Alexander Avatar answered Oct 31 '25 21:10

Alexander



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!