简体   繁体   English

如何使用IStringLocalizer从ASP.NET Core Controller获取本地化字符串?

[英]How to get localized string from ASP.NET Core Controller using IStringLocalizer?

Kinda confused here, super simple hello-world example of localization in ASP.Net Core 2.0. 有点困惑在这里,ASP.Net Core 2.0中的本地化超级简单的hello-world示例。 My About page is set up to render two localized strings: 我的“ 关于”页面设置为呈现两个本地化字符串:

  1. From the view (using IViewLocalizer ) 从视图(使用IViewLocalizer
  2. From code (using IStringLocalizer<HomeController> via the controller) 从代码(使用IStringLocalizer<HomeController>通过控制器)

The code in the controller refuses to get the loc string appropriately. 控制器中的代码拒绝正确获取loc字符串。 This is not complicated, what obvious things am I missing? 这并不复杂,我错过了哪些明显的事情?

About.cshtml About.cshtml

@using Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

<p>@Localizer["Use this area to provide additional information."]</p>

^ Note the two strings: "Message" will be localized from code using IStringLocalizer (see HomeController below), and the @Localizer will use the IViewLocalizer class. ^注意两个字符串:“Message”将使用IStringLocalizer从代码本地化(请参阅下面的HomeController),@ Local将使用IViewLocalizer类。

HomeController.cs HomeController.cs

public class HomeController : Controller
{
    private readonly IStringLocalizer _localizer;

    public HomeController(IStringLocalizer<HomeController> localizer)
    {
       _localizer = localizer;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = _localizer["Your application description page."];

        return View();
    }
}

Startup.cs (relevant parts) Startup.cs (相关部分)

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(options => options.ResourcesPath = "Resources");

        services.AddMvc()
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
            .AddDataAnnotationsLocalization();

        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("fr-CH"),
            };

            options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
        app.UseRequestLocalization(locOptions.Value);

        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

Resources: 资源:

Views.Home.About.fr-CH.resx Views.Home.About.fr-CH.resx

^ with two values in it: ^中有两个值:

  • "Use this area to provide additional information." “使用此区域提供更多信息。” = "Use this area... success for fr-CH!" =“使用这个区域...... fr-CH成功!”
  • "Your application description page." “您的应用程序说明页面。” = "Your app descript... success for fr-CH!" =“你的应用程序描述...... fr-CH的成功!”

My Results: 我的结果:

localhost:56073/Home/About 本地主机:56073 /首页/

^ This renders the strings as expected in en-US (default finds nothing, uses the strings actually hard coded) ^这会在en-US中呈现预期的字符串(默认找不到任何内容,使用实际硬编码的字符串)

localhost:56073/Home/About?culture=fr-CH 本地主机:56073 /首页/关于文化= FR-CH

^ This renders ONLY the 2nd string: "Use this area... success for fr-CH!", which clearly means all the code wired up is working and finding the fr-CH.resx as expected. ^这只呈现第二个字符串:“使用此区域... fr-CH成功!”,这显然意味着所有连接的代码都正常工作并按预期找到fr-CH.resx。

BUT, the first string (set in code as ViewData["Message"] ) does NOT get the fr-CH version! 但是,第一个字符串(在代码中设置为ViewData["Message"] )没有获得fr-CH版本! It's like the IStringLocalizer<HomeController> failed to realize there was a lang specified, or failed to find the fr-CH.resx that is clearly available. 这就像IStringLocalizer<HomeController> 没有意识到指定了lang,或者找不到明显可用的fr-CH.resx。

Why??? 为什么???

Also BTW, I tried using the ShareResource example too (see link below), and passed in the factory to the HomeController ctor as IStringLocalizerFactory factory , also with no love, still not getting the fr-CH resource. 另外顺便说一句,我也试过使用ShareResource示例(参见下面的链接),并将工厂作为IStringLocalizerFactory factory传递给HomeController ctor,也没有爱,仍然没有获得fr-CH资源。 Sigh. 叹。

Other notes: 其他说明:

Using this as my primary reference: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization 使用它作为我的主要参考: https//docs.microsoft.com/en-us/aspnet/core/fundamentals/localization

Using VS 2017, latest updates, with ASP.Net Core 2.0 使用VS 2017,最新更新,使用ASP.Net Core 2.0

You are using IStringLocalizer<HomeController> as localizer in the controller to find the localized string. 您正在控制器中使用IStringLocalizer<HomeController>作为本地化程序来查找本地化字符串。 The localizer will look in Resources folder to find YouControllerNameSpace.HomeController resource file and since it doesn't find it, it will return the original key which you passed to the localizer. 本地化程序将在Resources文件夹中查找YouControllerNameSpace.HomeController资源文件,因为它找不到它,它将返回您传递给本地化程序的原始密钥。

To solve the problem, you can use either of following options: 要解决此问题,您可以使用以下任一选项:

  • Inject IStringLocalizer<T> 注入IStringLocalizer<T>
  • Inject IStringLocalizerFactory 注入IStringLocalizerFactory

For more information about resource file names, take a look at Resource file naming section in documentations. 有关资源文件名的更多信息,请查看文档中的“ 资源文件命名”部分。

Inject IStringLocalizer<T> 注入IStringLocalizer <T>

Using this option, you should have a resource file with the same name as full name of T, in your case, the controller code should be the same as it is: 使用此选项,您应该拥有一个与T的全名同名的资源文件,在您的情况下,控制器代码应该与它相同:

IStringLocalizer _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
   _localizer = localizer;
}

For the resource file: 对于资源文件:

  • Make sure you have YouControllerNameSpace.HomeController resource file. 确保您拥有YouControllerNameSpace.HomeController资源文件。 ( YouControllerNameSpace is just a placeholder, use your controller namespace.) YouControllerNameSpace只是一个占位符,使用您的控制器命名空间。)
  • Make sure you have the specified string in resource file. 确保资源文件中包含指定的字符串。
  • Make sure you have resource files for different cultures. 确保您拥有不同文化的资源文件。

Inject IStringLocalizerFactory 注入IStringLocalizerFactory

Using this option you can use any file as resource file. 使用此选项,您可以将任何文件用作资源文件。 For example if you want to read resources from Views.Home.About resource file, you should change the controller code to this: 例如,如果要从Views.Home.About资源文件中读取资源,则应将控制器代码更改为:

IStringLocalizer _localizer;
public HomeController(IStringLocalizerFactory factory)
{
    _localizer = factory.Create("Views.Home.About", 
        System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
}

For the resource file: 对于资源文件:

  • Make sure you have Views.Home.About resource file. 确保您有Views.Home.About资源文件。
  • Make sure you have the specified string in resource file. 确保资源文件中包含指定的字符串。
  • Make sure you have resource files for different cultures. 确保您拥有不同文化的资源文件。

Try the technique described by tmg in this answer . 尝试在这个答案中 tmg描述的技术。

Specifically, try adding the lines 具体来说,尝试添加行

options.RequestCultureProviders = new List<IRequestCultureProvider>
{
    new QueryStringRequestCultureProvider(),
    new CookieRequestCultureProvider()
};

to your ConfigureServices() function 到您的ConfigureServices()函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Asp.Net Core获取控制器中的本地化显示属性 - Get localized display attribute in a controller using Asp.Net Core Asp.Net Core - 访问 IStringLocalizer 实例形式 static class - Asp.Net Core - Access IStringLocalizer instance form static class ASP.NET Core:在控制器类中使用“DisplayFor”方法来检索本地化的枚举显示属性 - ASP.NET Core: using "DisplayFor" method in controller class to retrieve localized enum display attribute 使用ASP.NET MVC 5,如何在View中获取Enum值的本地化DisplayAttribute字符串? - Using ASP.NET MVC 5, how do I get the localized DisplayAttribute string for an Enum value in a View? 如何处理 ASP.NET Core 中的本地化内容? - How to handle localized content in ASP.NET Core? ASP.NET Core - 从 controller 类型获取路由 - ASP.NET Core - get route from controller type ASP.NET Core 如何让 UserManager 在控制器中工作? - ASP.NET Core How to get UserManager working in controller? 在Asp.Net Core Controller中获取用户名 - Get username in Asp.Net Core Controller 如何使用 AJAX POST 对象并使用 ASP.NET Core MVC 控制器获取? - How to POST object using AJAX and get with ASP.NET Core MVC controller? asp.net核心-如何将变量从控制器传递到过滤器 - asp.net core - How to pass variable from controller to filter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM