【问题标题】:How to create a link to switch language in ASP.NET Core 2.2?如何在 ASP.NET Core 2.2 中创建切换语言的链接?
【发布时间】:2019-04-02 10:47:27
【问题描述】:

一个网站支持多种语言。支持多语言的代码(包括路线)已经到位并正在运行。

使用RouteDataRequestCultureProvider 设置本地化,如https://joonasw.net/view/aspnet-core-localization-deep-dive 所述。

app.UseRouter(routes =>
{
    routes.MapMiddlewareRoute("{culture=en-US}/{*mvcRoute}", subApp =>
    {
        subApp.UseRequestLocalization(localizationOptions);

        subApp.UseMvc(mvcRoutes =>
        {
             // Routes are here
        }   
    });
});

如何创建一个通用标签,以不同的语言显示当前页面?

理想情况下,我只需指定此链接应指向哪种语言,并且应保留所有其他路由参数(如当前控制器、当前操作、当前路由模型),以便我可以在 @987654324 中拥有此链接@?

【问题讨论】:

  • 我认为我还没有完全理解这一点。您是否正在考虑让用户能够在不改变 UIculture 的情况下(暂时)将一页切换到另一种语言?如果是这样,您是在考虑一种特定的语言还是应该以任何方式动态?
  • 不,链接应该指向当前页面/视图,只是使用不同的语言(在大多数情况下,如果当前页面是 /en-US/about,链接应该指向 /de-德/约)。

标签: c# asp.net-core


【解决方案1】:

我设法通过语言下拉列表的部分视图来做到这一点。

  • 首先通过将RequestLocalizationOptions 注入部分视图来获取支持的文化列表
  • 将路由数据值和查询字符串参数也收集到字典中,因此如果您有如下链接,它将捕获所有参数。

    /zh-CN/Products/?page=5&keyword=bla-bla-bla

  • 在支持的区域性中循环以创建链接并将{culture} 路由值替换为循环中的适当值。唯一需要考虑的是在全局路由中定义{culture}。

这是我的_Languages.cshtml 部分视图:

@using Microsoft.AspNetCore.Builder
@using Microsoft.Extensions.Options

@inject IOptions<RequestLocalizationOptions> LocOps

@{
    var requestCulture = CultureInfo.CurrentCulture;

    var supportedCultures = LocOps.Value.SupportedUICultures

        .Select(c => new SelectListItem
        {
            Value = $"{c.Name}",
            Text = $"{c.DisplayName}"
        }).ToList();

    var routeData = new Dictionary<string, string>();

    foreach (var r in ViewContext.RouteData.Values)
    {
        routeData.Add(r.Key, r.Value.ToString());
    }

    foreach(var qs in Context.Request.Query)
    {
        routeData.Add(qs.Key, qs.Value);
    }
}

<div class="dropdown">
    <a class="btn-sm btn-default border border-secondary dropdown-toggle" href="#" role="button" id="dropdownLang" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        @($"{requestCulture.DisplayName}")
    </a>

    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownLang">
        @foreach (var culture in supportedCultures)
        {
            if (culture.Value.ToLower() != requestCulture.Name.ToLower())
            {
                // replace {culture} value with the one from the list
                routeData["culture"] = culture.Value;

                <a class="dropdown-item small"
                   asp-all-route-data="@routeData">
                    @culture.Text
                </a>
            }
        }
    </div>
</div>

顺便说一句,我正在使用引导程序 4。

更新

我创建了一个 nuget 包,它用一行代码创建了一个语言导航菜单:)

  • 安装nuget包
PM > Install-Package LazZiya.RazorLibrary -Version 1.0.1
  • 创建语言导航下拉菜单:
<partial name="/Areas/LazZiya/Pages/_LanguageMenu.cshtml" />

与 .NetCote 2.1 或更高版本以及 bootstrap 4 兼容

  • 注意:路由键名必须为culture

更新 2 (14.04.2019)

我创建了一个标签助手,它支持当前 dotnet 核心框架的所有版本,以根据支持的文化或手动选择的文化列表创建语言导航。

安装 nuget 包(它还包含另一个有用的标签助手):

Install-Package LazZiya.TagHelpers -Version 2.0.0

将标签助手添加到 _ViewImports.cshtml

@addTagHelper *, LazZiya.TagHelpers

创建语言导航:

<language-nav view-context="ViewContext"></language-nav>

更多详情请访问project website,见live demos


【讨论】:

    【解决方案2】:

    这不是超级优雅,但应该可以解决问题。这里仅作为 en-US 和 de-DE 的示例:

    var switchLang = new Dictionary<string, string>{{"de-DE", "en-US"}, {"en-US", "de-DE"}};
    var controller = Html.ViewContext.RouteData.Values["controller"].ToString();
    var action = Html.ViewContext.RouteData.Values["action"].ToString();
    var lang = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
    var newLang = lang;
    switchLang.TryGetValue(lang, out newLang);
    

    然后,您可以使用变量 controller、action 和 newLang 来构建到其他语言的 ActionLink。我只是在我的 _Layout.cshtml 中放了一行来显示

    的值
    var url = string.Format("{0}/{1}/{2}",newLang, controller, action);
    

    看起来还不错。

    【讨论】:

    • 是的,这听起来真的像一个紧急黑客 :) 我希望有一个更优雅/通用的方法来实现这一点。
    • 如果您更清楚地定义何时使用什么语言链接以及默认使用什么,这可能会有所帮助。还有语言路由究竟是如何发生的。
    猜你喜欢
    • 1970-01-01
    • 2014-07-19
    • 2019-05-10
    • 1970-01-01
    • 2012-04-04
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多