В чем разница между IRequestCultureFeature и CurrentCulture в Asp.Net Core? - PullRequest
0 голосов
/ 12 марта 2019

В действии контроллера эти переменные:

        var foo = Request.HttpContext.Features.Get<IRequestCultureFeature>()
                      .RequestCulture.Culture;
        var bar = Thread.CurrentThread.CurrentCulture;

Оба возвращают "en". В чем разница между ними и что лучше использовать с точки зрения определения языка пользователя, просматривающего сайт ??

1 Ответ

1 голос
/ 12 марта 2019

Согласно исходному коду из 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;
}

текущая культура запросов установлена ​​как для IRequestCultureFeature, так и для текущего CultureInfo (CultureInfo.CurrentCulture получает / устанавливает Thread.CurrentThread.CurrentCulture и, следовательно, они одинаковы). Таким образом, между этими методами нет никакой разницы с точки зрения получения современной культуры.

Основное отличие состоит в том, что IRequestCultureFeature привязан к текущему HttContext (http-запрос). И, по моему мнению, когда вы получаете культуру, используя IRequestCultureFeature, вы явно говорите, что вам нужна текущая культура запросов. И когда вы используете Thread.CurrentThread.CurrentCulture, не совсем ясно, что вы намерены получить культуру запросов. Поэтому я бы предпочел использовать IRequestCultureFeature из-за лучшей читаемости. И можно сказать, что это лучше для целей тестирования.

Но настройка культуры, с другой стороны, имеет разный эффект для каждого сценария. Если вы замените IRequestCultureFeature на следующий код

context.Features.Set<IRequestCultureFeature>(some request culture);

это только заменит функцию и не повлияет на что-либо еще (афаик после изучения некоторого исходного кода фреймворка). Но изменение культуры, как это

CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture; //namely this line has effect described bellow

напрямую повлияет на менеджер ресурсов и выбор локализаций. Просмотр исходного кода показывает зависимость от CultureInfo.CurrentUICulture

protected string GetStringSafely(string name, CultureInfo culture)
{
    if (name == null)
    {
        throw new ArgumentNullException(nameof(name));
    }

    var keyCulture = culture ?? CultureInfo.CurrentUICulture;
    //..
}

И простые тесты подтверждают это

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...