【问题标题】:Localization file not effective rendering a Razor page in MVC ASP.NET Core 2.2本地化文件在 MVC ASP.NET Core 2.2 中无法有效呈现 Razor 页面
【发布时间】:2019-07-07 20:01:24
【问题描述】:

我的 Razor 页面如下所示。

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
<h1>@Localizer["Index"]</h1>
...

我的 Startup.cs 包含以下内容。

public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddLocalization(a => a.ResourcesPath = "/");

  services.Configure<RequestLocalizationOptions>(a =>
  {
    CultureInfo[] supportedCultures = {
      new CultureInfo("sv-SE"),
      new CultureInfo("se")
    };
    a.DefaultRequestCulture = new RequestCulture("se");
    a.SupportedCultures = supportedCultures;
    a.SupportedUICultures = supportedCultures;
  });
  ...
}

我直接在项目的根目录中放置了一个名为 Controllers.HomeController.se.resx 的文件。控制器 HomeController 包含注入。

public class HomeController : Controller
{
  private readonly Context _context;
  private readonly IStringLocalizer<HomeController> _localizer;

  public HomeController(Context context, IStringLocalizer<HomeController> localizer)
  {
    _context = context;
    _localizer = localizer;
  }
  ...
}

应用程序不会崩溃呈现的字符串是 Index 而不是来自 RESX 文件的值。我试图尽可能地关注the docs,但显然我错过了一些东西。我需要帮助找出那将是什么。

我在构造函数中设置了断点并检查了 _localizer["Index"] 的值。正如预期的那样,未找到文件的标志设置为 true。检查 SearchedLocation 的值会给我 Web...Controllers.MemberController。我不知道这三个点是否是项目根目录中 RESX 文件的正确点。我也期待 se 在名称中的某处。

【问题讨论】:

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


    【解决方案1】:

    如果您想将资源文件放在项目的根目录中,您应该将ResourcesPath 设置为如下

    services.AddLocalization(a => a.ResourcesPath = ""); //empty string
    

    使用此设置SearchedLocation 将为您提供Web.Controllers.MemberController,它指向项目根目录中的Controllers.MemberController.resx 文件。

    要在视图中使用本地化,您必须遵循Views.{ControllerName}.{ViewName}.resx 模式。例如,如果您在其中有 HomeControllerAbout 视图,则需要有 Views.Home.About.resx 文件才能使用本地化。

    搜索本地化文件时遵循的另一个约定资源阅读器是搜索相应文件夹中的文件,而不是按点分隔的名称。例如,如果 ResourcesPath 设置为 "Resources",则以下变体是相等的

    Resources.Views.Home.About.resx
    Resources\Views.Home.About.resx
    Resources\Views\Home.About.resx
    Resources\Views\Home\About.resx
    

    因此可以按文件夹来组织本地化文件。

    并且您没有指定您在Startup.cs 中添加了app.UseRequestLocalization()。如果您不这样做,您的应用程序将无法确定请求文化,并且它将始终指向默认资源文件。阅读更多in the docs

    注意

    有两种方法可以为请求本地化配置RequestLocalizationOptions,通过services.Configure&lt;RequestLocalizationOptions&gt; 或将构造的选项对象(或委托)传递给app.UseRequestLocalization。实际上,这些方法之间没有区别,它们在本地化中间件方面完全相等。但是,如果在应用程序的任何时候您需要获得RequestLocalizationOptions,您将无法获得传递给app.UseRequestLocalization 的值。但是使用services.Configure&lt;RequestLocalizationOptions&gt; 很容易实现(这是in the docs 描述的一般方法)

    public class HomeController : Controller
    {
        private readonly RequestLocalizationOptions _requestLocalizationOptions;
    
        public HomeController(IOptions<RequestLocalizationOptions> options)
        {
            _requestLocalizationOptions = options.Value;
        }
    
        //..
    }
    

    【讨论】:

    • 你的赏金会在 23 小时 59 分钟内到来,伙计。该网站现在不允许我提供它。对不起。
    • 现在,如果没有指定其他内容,默认资源文件是什么?如果我注入 IStringLocalization,那会指向没有语言代码的 Lang.resx 吗?
    • @DonkeyBanana 不,它将指向具有与请求文化相对应的语言代码的 Lang.resx。您可以通过在地址栏中添加?culture=sv-SE 来测试不同的文化
    • 您的赏金已被授予。我差点忘了。好东西这么提醒。话虽如此,这个问题当然得到了回答,但我想知道您是否有关于在术语之间切换 的好方法的快速提示。目前,我将默认语言设置为 sv 并且它工作得很好。但是,迟早,我想进步并能够选择语言。在菜单中,我可以添加一个切换器,所以 GUI 部分不是问题。但是更改正在使用的 RESX 和讲述所选术语等的业务逻辑是我担心我会做出糟糕选择的领域。
    • @DonkeyBanana 最简单的方法是使用 cookie 本地化。创建接受文化作为字符串的操作,从中创建RequestCulture,然后通过使用CookieRequestCultureProvider.MakeCookieValue 和键CookieRequestCultureProvider.DefaultCookieName 设置cookie 值来设置响应cookie。当您设置 cookie 时,它​​将在后续请求中使用,因此可以说它将被“存储”。如果您确实想将用户文化存储在数据集中,那么您需要实现自己的RequestCultureProvider 以由当前用户从数据库中获取文化。希望对您有所帮助。
    猜你喜欢
    • 2021-07-04
    • 2022-01-20
    • 2013-05-30
    • 1970-01-01
    • 2019-09-17
    • 2020-08-22
    • 2019-11-12
    • 2020-06-16
    • 2021-09-25
    相关资源
    最近更新 更多