改变控制器ASP.Net 5中的文化

时间:2018-05-09 16:22:09

标签: c# asp.net asp.net-core

我已经四处寻找,但却无法找到适合我的答案。

我的问题是:如何在控制器方法中设置当前响应的文化。

方案如下。我们有一个Web应用程序的一般区域,它通过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(&#34; da-DK&#34;))使用以下代码,这是我尝试解决问题的方法:

    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或默认语言设置的语言,但是他们的网址不会在那里定义语言。

如果无法通过直接设置当前文化来解决这个问题,是否可以通过为Web应用程序的这个特定部分设置路由区域来解决这个问题?

提前致谢!

编辑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接口,所以这一切都可以用几行代码完成。

0 个答案:

没有答案