Изменить культуру в контроллере ASP.Net 5 - PullRequest
0 голосов
/ 09 мая 2018

Я искал вокруг и не смог найти ответ, который работал для меня.

Мой вопрос: как установить культуру текущего ответа в методе контроллера.

Сценарий выглядит следующим образом.У нас есть общая область веб-приложения, которая работает с культурой, установленной через cookie, и работает нормально.

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

В методе контроллера, получающем запрос, я добавляю изменение культуры в файл cookie, но возвращаемое представление по-прежнему отображается на предыдущем языке.Обновление страницы будет отображать представление на правильном языке, поскольку cookie теперь имеет правильные значения.

Я хотел бы также изменить культуру текущего запроса помимо cookie, чтобывозвращенное представление отображается на правильном языке.

Код моего контроллера выглядит следующим образом:

    [Route("{organizationId}/{arrangementId}")]
    public IActionResult LandingPage(int organizationId, int arrangementId, [FromQuery] string lang, [FromQuery] bool? allowup)
    {
        if (organizationId <= 0 || arrangementId <= 0)
        {
            return RedirectToAction("Index");
        }

        _utils.SetLoginRedirectUrl($"/Skolevaccination/Questionnaire/{organizationId}/{arrangementId}", Response);

        SetLanguage(!string.IsNullOrWhiteSpace(lang) ? lang : "da-DK");


        ViewBag.allowup = allowup ?? false;

        return View("Index");
    }

    private void SetLanguage(string lang)
    {
        string cultureCookieValue;
        switch (lang)
        {
            case "gb":
            case "en-GB":
                cultureCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("en-GB"));
                _cultureService.SetCulture(new CultureInfo("en-GB"));
                break;
            case "dk":
            case "da-DK":
                cultureCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("da-DK"));
                _cultureService.SetCulture(new CultureInfo("da-DK"));
                break;
            default:
                _logger.LogInformation($"Trying to set a language {lang}, which isn't supported.");
                return;
        }
        Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, cultureCookieValue);
    }

При вызове _cultureService.SetCulture (new CultureInfo ("da-DK")) используетсяследующий код, который является моей попыткой решить проблему:

    public void SetCulture(CultureInfo cultureInfo)
    {
        if (!GetSupportedCultures().Contains(cultureInfo))
        {
            throw new CultureNotFoundException("The given culture is not supported.");
        }

        Thread.CurrentThread.CurrentUICulture = cultureInfo;
        Thread.CurrentThread.CurrentCulture = cultureInfo;

        //CultureInfo.CurrentCulture = cultureInfo;
        //CultureInfo.CurrentUICulture = cultureInfo;
    }

Как видно, я попытался установить текущую культуру потока и также использовать статические методы в CultureInfo (закомментированные строки).

Во многих постах, которые я нашел в Интернете, упоминалось, что настройка культуры потока была тем, что использовалась до ASP.Net 5 (ядро ASP.Net), и что все настройки культуры теперь установлены в файле запуска.Но если я изменю это в файле запуска, я изменю это для всего сайта, что не то, что мы хотим.И мне нужно также установить cookie, поскольку на последующих страницах в небольшой части всего веб-сайта должен использоваться язык, заданный с помощью URL-адреса, или язык по умолчанию, но в их URL-адресах язык не будет определен там.

Если это невозможно решить, установив текущую культуру напрямую, возможно, это можно решить, настроив область маршрутизации для этой конкретной части веб-приложения?

Заранее спасибо!


РЕДАКТИРОВАТЬ 2018/10/05

Я нашел решение, посмотрев ближе на вид и его IViewLocalizer.

Посмотрев ближе документацию наЯ обнаружил, что в классах локализаторов можно использовать их метод WithCulture.Это возвращает новый локализатор для тех же строк, но для данной культуры.

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

Мое решение закончилось следующим образом:

В контроллере:

    private void SetLanguage(string lang, string defaultLang)
    {
        if (string.IsNullOrWhiteSpace(lang) || !_cultureService.IsSupportedCulture(lang)) {
            _logger.LogInformation($"Tried to change culture to unsupported culture (to {lang}). Culture has been set to default culture {defaultLang}.");
            lang = defaultLang;
        }

        string cultureCookieValue;
        switch (lang)
        {
            case "gb":
            case "en-GB":
                cultureCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("en-GB"));
                _localizer = _localizer.WithCulture(new CultureInfo("en-GB"));
                ViewBag.changeCulture = true;
                ViewBag.lang = "en-GB";
                break;
            case "dk":
            case "da-DK":
                cultureCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("da-DK"));
                _localizer = _localizer.WithCulture(new CultureInfo("da-DK"));
                ViewBag.changeCulture = true;
                ViewBag.lang = "da-DK";
                break;
            default:
                _logger.LogInformation($"Trying to set a language {lang}, which isn't supported.");
                return;
        }
        Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, cultureCookieValue);
    }

При вызове этого метода в контроллере я установил некоторые данные в сумке представления, которая используется в представлении для создания там нового локализатора:

@inject IViewLocalizer ViewLocalizer

@{
    IHtmlLocalizer Localizer = ViewLocalizer;
    if (ViewBag.changeCulture) {
        var lang = ViewBag.lang;
        Localizer = Localizer.WithCulture(new CultureInfo(lang));
    }
    var allowUserPasswordLogin = ViewBag.allowup;
}

При вызове метода WithCulture возвращается тип IHtmlLocalizer, который не может быть приведен обратно к IViewLocalizer, но IViewLocalizer расширяет интерфейс IHtmlLocalizer, поэтому все работает с несколькими строками кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...