Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在asp.net core中获取.resx文件字符串_C#_Asp.net Core - Fatal编程技术网

C# 如何在asp.net core中获取.resx文件字符串

C# 如何在asp.net core中获取.resx文件字符串,c#,asp.net-core,C#,Asp.net Core,如何在asp.net core中获取resx文件字符串? 我在mvc中使用ResxResourceReader获取字符串。但是我在asp.net core中无法得到相同的结果。旧版本(如asp.net中)是创建一个默认资源文件,如MyResources.resx和其他用于不同区域性的文件MyResources.fr.resx。。。并使用MyResources.MyValue1从中检索值。创建MyResources.resx将生成一个.cs文件,其中包含所有资源值作为静态属性 .Net Core建

如何在asp.net core中获取resx文件字符串? 我在mvc中使用ResxResourceReader获取字符串。但是我在asp.net core中无法得到相同的结果。

旧版本(如asp.net中)是创建一个默认资源文件,如MyResources.resx和其他用于不同区域性的文件MyResources.fr.resx。。。并使用MyResources.MyValue1从中检索值。创建MyResources.resx将生成一个.cs文件,其中包含所有资源值作为静态属性

.Net Core建议使用
IStringLocalizer
,其中T是您创建的一个类,它与资源文件的名称匹配。您可以在没有任何资源文件的情况下开始开发,然后再添加它们。您必须在控制器上注入(IStringLocalizerlocalizer),然后使用_localizer[“MyValue1”]获取值


您可以查看.net core官方文档

。net core改变了资源文件的工作方式,我觉得这种方式不够标准且令人困惑(我花了几天时间才弄清楚),但您需要做的是:

  • 将以下代码添加到Startup.cs-注意:更改您支持的语言,“Resources”的ResourcePath将只是稍后存储.resx文件的文件夹
  • 如评论中所述:如果您计划将您的SharedResource文件放在Resources文件夹中,并将其名称空间设置为Resources结尾,则不要设置
    o.ResourcesPath=“Resources”
    只需使用
    服务。AddLocalization()
    ,否则它将开始查找Resources.Resources文件夹,该文件夹不存在

    services.AddLocalization(o=>o.ResourcesPath=“Resources”);
    配置(选项=>
    {
    var supportedCultures=new[]
    {
    新文化信息(“美国”),
    新文化信息(“en GB”),
    新文化信息(“de de”)
    };
    options.DefaultRequestCulture=新的RequestCulture(“en-US”、“en-US”);
    //必须明确说明应用程序支持哪些区域性。
    //这些是应用程序支持的格式化区域性
    //数字、日期等。
    options.SupportedCultures=SupportedCultures;
    //这些是应用程序对UI字符串支持的区域性,
    //也就是说,我们为您提供了本地化的资源。
    options.supportedCultures=supportedCultures;
    });
    
  • 在任何要存储resx文件的项目中创建一个文件夹-默认情况下,将其称为“资源”

  • 创建一个具有特定区域性和稍后将查找的文件名的新resx文件:如果您有一个共享文件,则可以执行以下操作:SharedResource.en-US.resx。然后关闭自动代码生成,因为它现在没用了

  • 在与resx文件相同的位置创建一个名为“SharedResource”的类。它可以是空白的,只是需要在那里,以便您以后可以引用它

  • 无论您想在哪里使用资源,IoC inject(在本例中)都会使用名为“\u localizer”或其他名称的IStringLocalizer

  • 最后,您可以通过执行_localizer[“My_Resource_Name”]来引用资源文件中的条目

  • 通过在同一文件夹中创建名为“SharedResource.de-de.resx”或其他名称的新resx文件来添加另一种语言

  • “资源”文件夹将用于所有程序集,以查找所有程序集。因此,这个文件夹可能会变得非常杂乱,尤其是当您开始在这里获取特定于视图的内容时

    我知道开发人员在这里试图做什么,但他们为了达到目的放弃了太多。人们可以编写代码并添加翻译内容,而无需实际翻译任何内容。他们从一开始就让开发人员更容易记住翻译,但最终让实际使用翻译的开发人员更容易记住翻译。现在我们无法自动生成任何内容。为了访问这些翻译,我们必须向它们注入一个引用(除非您想使用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];
    }
    
    公共接口资源
    {
    字符串错误UnexpectedNumberOfRowsSaved{get;}
    字符串ErrorNoRecordsSaved{get;}
    字符串错误并发{get;}
    字符串ErrorGeneric{get;}
    字符串RuleAlreadyInUse{get;}
    字符串RuleDoesNotExist{get;}
    字符串规则无效{get;}
    字符串RuleMaxLength{get;}
    需要字符串规则{get;}
    }
    公共类CommonResource:ICommonResource
    {
    专用只读IStringLocalizer\u localizer;
    公共公共资源(IStringLocalizer定位器)=>
    _定位器=定位器;
    公共字符串ErrorUnexpectedNumberOfRowsSaved=>GetString(名称(ErrorUnexpectedNumberOfRowsSaved));
    public string ErrorNoRecordsSaved=>GetString(nameof(ErrorNoRecordsSaved))
    
    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];
    }