加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何在asp.net核心中获取.resx文件字符串

发布时间:2020-12-15 08:09:08 所属栏目:百科 来源:网络整理
导读:如何在asp.net核心中获取resx文件字符串? 我在mvc中使用ResxResourceReader获取字符串.但是我无法在asp.net核心中获得相同的功能. 解决方法 .NET Core改变了资源文件的工作方式,我认为这种方式低于标准并且令人困惑(花了我几天才弄清楚),但这是你需要做的:
如何在asp.net核心中获取resx文件字符串?
我在mvc中使用ResxResourceReader获取字符串.但是我无法在asp.net核心中获得相同的功能.

解决方法

.NET Core改变了资源文件的工作方式,我认为这种方式低于标准并且令人困惑(花了我几天才弄清楚),但这是你需要做的:

>将以下代码添加到Startup.cs – 注意:更改您支持的语言,“资源”的ResourcePath将只是您以后存储.resx文件的文件夹

services.AddLocalization(o => o.ResourcesPath = "Resources");
    services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),new CultureInfo("en-GB"),new CultureInfo("de-DE")
        };
        options.DefaultRequestCulture = new RequestCulture("en-US","en-US");

        // You must explicitly state which cultures your application supports.
        // These are the cultures the app supports for formatting 
        // numbers,dates,etc.

        options.SupportedCultures = supportedCultures;

        // These are the cultures the app supports for UI strings,// i.e. we have localized resources for.

        options.SupportedUICultures = supportedCultures;
    });

>在要存储resx文件的任何项目中创建一个文件夹 – 默认情况下,将其命名为“Resources”.
>创建一个新的resx文件,其中包含您稍后将查找的特定文化和文件名:如果您有共享文件,则可以执行以下操作:SharedResource.en-US.resx.然后关闭自动代码生成,因为它现在没用.
>在与resx文件相同的位置创建一个名为“SharedResource”的类.它可以是空白的,它只需要在那里,以便您以后可以参考它.
>无论您想在何处使用资源,IoC注入(在此示例中)IStringLocalizer< SharedResource>名称为“_localizer”或其他什么.
>最后,您可以通过执行_localizer [“My_Resource_Name”]来引用资源文件中的条目
>通过在同一文件夹中创建名为“SharedResource.de-DE.resx”的新resx文件或其他任何内容来添加另一种语言.

将在所有程序集中使用“Resource”文件夹以查看所有程序集.因此,这个文件夹可能会变得非常混乱,特别是如果你开始在这里获取视图特定的东西.

我看到开发人员在这里尝试做什么,但是他们放弃了太多而无法到达那里.人们可以编码和添加翻译内容,而无需实际翻译任何内容.他们让开发人员从一开始就更容易考虑翻译,但他们最终会为实际使用翻译的开发人员提供更多的工作.现在我们无法自动生成任何内容.我们必须向IoC注入对翻译的引用才能访问它们(除非你想使用ServiceLocater反模式,否则不再是静态的).所有的名字都是硬编码的字符串,所以现在如果你拼写错误的翻译,它只会吐回你给它的字符串,打破了首先翻译的目的,这意味着你可能需要一个包装器这样你就不会依赖常数了.

说实话,我简直不敢相信有人认为这是个好主意.无论如何,为什么不关心翻译的开发者会向后弯腰?

我最终围绕这种风格创建了一个包装器.唯一的好处是,如果您决定从数据库获取资源,则不需要更改上面的代码,但现在您必须添加资源条目,将其添加到接口,然后实现它以拉动它再次退出.我使用了nameof()所以我不需要使用常量,但这仍然很脆弱,就好像属性名称或resx文件名更改一样,它会破坏翻译而不会发生任何崩溃 – 我可能需要进行集成测试确保我没有得到我发送的相同值:

public interface ICommonResource
{
    string ErrorUnexpectedNumberOfRowsSaved { get; }
    string ErrorNoRecordsSaved { get; }
    string ErrorConcurrency { get; }
    string ErrorGeneric { get; }

    string RuleAlreadyInUse { get; }
    string RuleDoesNotExist { get; }
    string RuleInvalid { get; }
    string RuleMaxLength { get; }
    string RuleRequired { get; }
}

public class CommonResource : ICommonResource
{
    private readonly IStringLocalizer<CommonResource> _localizer;

    public CommonResource(IStringLocalizer<CommonResource> localizer) =>
        _localizer = localizer;

    public string ErrorUnexpectedNumberOfRowsSaved => GetString(nameof(ErrorUnexpectedNumberOfRowsSaved));
    public string ErrorNoRecordsSaved => GetString(nameof(ErrorNoRecordsSaved));
    public string ErrorConcurrency => GetString(nameof(ErrorConcurrency));
    public string ErrorGeneric => GetString(nameof(ErrorGeneric));

    public string RuleAlreadyInUse => GetString(nameof(RuleAlreadyInUse));
    public string RuleDoesNotExist => GetString(nameof(RuleDoesNotExist));
    public string RuleInvalid => GetString(nameof(RuleInvalid));
    public string RuleMaxLength => GetString(nameof(RuleMaxLength));
    public string RuleRequired => GetString(nameof(RuleRequired));

    private string GetString(string name) =>
        _localizer[name];
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读