針對 ASP.NET Core 當地語系化進行疑難排解

作者為 Hisham Bin Ateya

本文提供如何診斷 ASP.NET Core 應用程式當地語系化問題的指示。

當地語系化組態問題

當地語系化中介軟體順序
應用程式可能會因為當地語系化中介軟體並未如預期般排序而無法當地語系化。

若要解決此問題,請確定當地語系化中介軟體的註冊順序早於 MVC 中介軟體。 否則不會套用當地語系化中介軟體。

public void ConfigureServices(IServiceCollection services)
{
    services.AddLocalization(options => options.ResourcesPath = "Resources");

    services.AddMvc();
}

找不到當地語系化資源路徑

RequestCultureProvider 中支援的文化特性 (Culture) 與註冊的不相符

資源檔命名問題

ASP.NET Core 已為當地語系化資源檔命名預先定義了規則與方針,其詳細說明請參閱此處

缺少資源

找不到資源的常見原因包括:

  • 資源名稱在 resx 檔案或當地語系化工具要求中拼錯。
  • 某些語言的 resx 中缺少這項資源,但其他語言則有。
  • 如果您仍持續發生問題,請查看當地語系化記錄訊息 (在 Debug 記錄層級),以獲取所缺少資源的詳細資料。

提示:使用 CookieRequestCultureProvider 時,請確認當地語系化 cookie 值中的文化特性 (Culture) 未使用單引號。 例如,c='en-UK'|uic='en-US' 是無效的 cookie 值,而 c=en-UK|uic=en-US 則有效。

資源與類別庫的問題

ASP.NET Core 根據預設會提供讓類別庫能透過 ResourceLocationAttribute 找到資源檔的方法。

類別庫的常見問題包括:

  • 類別庫中缺少 ResourceLocationAttribute 會導致 ResourceManagerStringLocalizerFactory 找不到資源。
  • 資源檔命名。 如需詳細資訊,請參閱資源檔命名問題一節。
  • 變更類別庫的根命名空間。 如需詳細資訊,請參閱根命名空間問題一節。

CustomRequestCultureProvider 未如預期運作

RequestLocalizationOptions 類別有三個預設提供者:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

CustomRequestCultureProvider 可讓您自訂應用程式中提供當地語系化文化特性的方式。 當預設提供者不符合您的需求時,會使用 CustomRequestCultureProvider

  • 自訂提供者無法正常運作的常見原因在於它不是 RequestCultureProviders 清單中的第一個提供者。 若要解決此問題:

  • 將自訂提供者插入 RequestCultureProviders 清單中的位置 0,如下所示:

options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
  • 使用 AddInitialRequestCultureProvider 擴充方法將自訂提供者設定為初始提供者。

根命名空間問題

當組件的根命名空間與組件名稱不同時,當地語系化根據預設無法運作。 若要避免此問題,請使用 RootNamespace,其詳細說明請參閱這裡

警告

若專案名稱不是有效的 .NET 識別碼,就會發生這種情況。 例如,my-project-name.csproj 會使用根命名空間 my_project_name 和組件名稱 my-project-name,因而導致此錯誤。

資源與建置動作

如果您使用資源檔進行當地語系化,務必讓他們有適當的建置動作。 它們必須是內嵌資源,否則 ResourceStringLocalizer 找不到這些資源。

[GitHub 問題] 提供實用的問題解決秘訣