2017-04-03 87 views
2

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

+1

请参考[如何问一个好问题?](// stackoverflow.com/help/how-to-ask)和[如何创建一个最小,完整和可验证的示例](// stackoverflow.com/help/mcve)。 – Olaia

+1

我想以keyvalue对的形式访问resx文件中的条目。如何在dotnet核心中做到这一点 –

回答

0

旧版本的方式(如在asp.net)是创建像MyResources.resx和其他文件对不同文化MyResources.fr.resx一个默认的资源文件。 ..并从MyResources.MyValue1中检索它的值。创建MyResources.resx将生成一个包含所有资源值作为静态属性的.cs文件。

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

你可以看看在.NET核心官方文档here

+0

他们为什么要那样做?现在我们必须使用字符串,这会让你得到运行时崩溃... –

2

.NET核心改变资源文件的方式,我觉得是如何工作是分面值和混乱(我花了几天弄清楚),但这是你需要做什么:

  1. 下面的代码添加到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; 
        }); 
    
  2. 在你想存储resx文件的任何项目中创建一个文件夹 - 默认情况下,将其称为“资源”。

  3. 创建一个新的resx文件,其中包含您将在以后查找的特定文化和文件名:如果您有共享文件,则可以执行:SharedResource.en-US.resx。然后关闭自动代码生成,因为它现在是无用的。

  4. 在与resx文件相同的位置创建一个名为“SharedResource”的类。它可以是空白的,只需要在那里,以便稍后参考。

  5. 无论你想使用你的资源,IoC注入(在本例中)IStringLocalizer < SharedResource>名称为“_localizer”或其他东西。

  6. 最后,你可以通过做_localizer [“My_Resource_Name”]

  7. 通过创建名为“SharedResource.de-DE.resx”一个新的resx文件添加另一种语言或任何引用的资源文件中的条目,在同一个文件夹中。

“资源”文件夹将用于所有组件以查看所有组件。因此,这个文件夹可能会变得非常混乱,特别是如果你开始在这里获得视图特定的东西。

我看到了开发人员在这里试图做什么,但他们放弃了太多,以达到那里。人们可以编码并添加翻译内容,而无需实际翻译任何内容。他们让开发人员从一开始就可以更轻松地进行翻译,但最终让开发人员更多地使用翻译。现在我们不能自动生成任何东西。我们必须为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]; 
} 
+0

我相信你仍然可以使用'ResXFileCodeGenerator'来生成编译时道具(例如https://christianspecht.de/2017/11/29/fixing-resourcedesignercs-generation-in-net-core /)。 – Dejan

+0

我做到了,但是文化变化对我来说却被忽略了。 –

+0

在使用ASP.Net 5的旧项目中,我有一个独立的项目,其中包含一个带有所有翻译字符串的全局文件(例如:Translations.resx和Translations.fr.resx,Translations.nl.resx等)。 ASP.Net Core 2仍然可以吗?即使我不能使用第二个项目的文件。因为我找不到如何做到这一点。 –

相关问题