2017-04-03 93 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仍然可以嗎?即使我不能使用第二個項目的文件。因爲我找不到如何做到這一點。 –

相關問題