如何实现资源文件本地化ASP-NET.core?

问题描述 投票:0回答:1

我被要求在ASP-NET.core中实现资源文件的本地化。net.core 解决办法如下。

  • 资源文件必须在一个单独的项目中(如 "MyProject.Common"),才能在解决方案中的所有其他项目中使用。

  • 资源必须以 "部分 "来分割,例如,我们在Web项目中有以下3个区域。

    • Users,
    • Content,
    • Administration,

所以我被要求有类似于:

  • UsersResources.fr-CA.resx。
  • UsersResources.en-CA.resx。
  • ContentResources.fr-Ca.resx。
  • ...

我开始阅读本地化是AP-NET核心的文档,我有点搞不懂它是如何工作的.似乎并不像我被告知要做的事情是可能的.事情是,我可能需要在业务,视图和控制器中使用资源,所以我'寻找一种方法来实现它,使团队可以使用旧的方式,通过调用。

事情是,我可能需要使用资源的业务,视图和控制器,所以我在寻找一种方法来实现它,所以团队可以使用旧的方式,通过呼吁 ContentResources.MyCustomResource.

有什么办法可以接近它吗?

如果发现一个帖子,其中有人提到 https:/www.nuget.orgpackagesResXResourceReader.NetStandard.

但我不知道它是否适合我的需求... ...

编辑:

所以,试图实现Laz的共享资源解决方案。

到目前为止,在启动时,我有这样的功能:在? ConfigureServices :

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddDataAnnotationsLocalization(options => {
                            options.DataAnnotationLocalizerProvider = (type, factory) =>
                            factory.Create(typeof(SharedResources));

services.AddLocalization();

services.Configure<RequestLocalizationOptions>(
            opts =>
            {
                    /* your configurations*/
                    var supportedCultures = new List<CultureInfo>
                    {
                        new CultureInfo("en"),
                        new CultureInfo("fr")
                    };
                opts.DefaultRequestCulture = new RequestCulture("fr", "fr");
                opts.SupportedCultures = supportedCultures;
                opts.SupportedUICultures = supportedCultures;
            }
        );

并在 Configure :

app.UseRequestLocalization();
// used to force culture to fr but doen't seem to work
var cultureInfo = new CultureInfo("fr");
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

在MyProject.Common中,我有这样的结构。

MyProject.Common
-Resources
 --SharedResources.cs
  ---SharedResources.fr.resx
  ---SharedResources.en.resx
 --UsersResources.cs
  ---UsersResources.fr.resx
  ---UsersResources.en.resx

比方说,我想使用 SharedResources.在 SharedResources.en.resx 我增加了资源。enter image description hereIn SharedResources.fr.resx 我添加了资源。enter image description here

现在在我的 UserService,在 Business 层,我这样做。

 private readonly IStringLocalizer Localizer;

    public UserService(IStringLocalizerFactory factory)
    {
        var type = typeof(SharedResources);
        var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
        _localizer = factory.Create(type);
    }       

    public void Test()
    {
        var test = Localizer["Test"]; //using the key of resources file i want
    }

但我得到的结果是 test 变量是 "Test",也就是 "测试"。key 的资源,而不是 value...

asp.net-core localization resources
1个回答
1
投票

.net core的默认本地化设置可以基于以下几点 一个共享资源文件基于类名.

在你的情况下,你可以使用共享资源的方法,但是你必须在每个controllerclass中创建cutomized localizer,为工厂提供所需的资源类型。

首先创建一个包含所需资源的类库,为每个你想要的资源类型创建一个public dummy类,这样类库结构就可以像下面这样。

// SharedResourcesLibrary.csproj

- UsersResources.cs
 - UsersResources.fr-ca.resx
 - UsersResources.en-ca.resx

- ContentResources.cs
  - ContentResources.fr-ca.resx
  - ContentResources.en-ca.resx

...

虚类是空的,它们只是作为调用相关resx文件的类型。

// Dummy users resources class
public class UsersResources { }

然后将ResourcesLibrary项目引用到其他项目中后,就可以通过调用相关资源类型(虚类)来使用资源了。

using SharedResourcesLibrary;

public class UsersController : Controller
{
    private readonly IStringLocalizer _localizer;

    public UsersController(IStringLocalizerFactory factory)
    {
        var type = typeof(UsersResources);
        _localizer = factory.Create(type);
    }       

    public IActionResult About()
    {
         ViewData["Message"] = _localizer["Welcome."];
    }
}

要使用其他资源,只需使用相关资源类型创建本地化器。


另一种方法可以通过创建自定义的多个 IStringLocalizer根据你的区域,然后将它们注入控制器中。

// Create one localizer for each area
public class UsersLocalizer : IStringLocalizer
{
    private readonly IStringLocalizer _localizer;

    public UsersLocalizer(IStringLocalizerFactory factory)
    {
        var type = typeof(UsersResources);
        var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
        _localizer = factory.Create(type);
    }

    public LocalizedString this[string name] => _localizer[name];

    public LocalizedString this[string name, params object[] arguments] => _localizer[name, arguments];

    // ...
}

同样,你也可以为其他区域创建本地化器......然后在启动时注册。

services.AddTransient<IStringLocalizer, UsersLocalizer>();
services.AddTransient<IStringLocalizer, AdminsLocalizer>();
services.AddTransient<IStringLocalizer, ContentLocalizer>();
// ...

这样一来,所有的本地化器都会被注册,如果你只是简单地注入... IStringLocalizer 它将获得最后注册的一个,因为所有的本地化器都实现了相同的 IStringLocalizer 接口。

所以,你必须进行类型选择,以注入正确的定位器。

public UsersController : Controller
{
    private readonly IStringLocalizer _localizer;

    public UsersController(IEnumerable<IStringLocalizer> localizers)
    {
        _localizer = localizers.FirstOrDefault(x => x.GetType() == typeof(UsersLocalizer));
    }

    public IActionResult About()
    {
        ViewData["Message"] = _localizer["Welcome."];
    }
}

你可以参考这篇文章,了解不同的方式。在Asp.Net Core中用同一接口注册多个实现

© www.soinside.com 2019 - 2024. All rights reserved.