ASP.NET Core Blazor のグローバリゼーションおよびローカライズ
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
この記事では、異なるカルチャや言語のユーザーにグローバル化およびローカライズされたコンテンツをレンダリングする方法について説明します。
グローバライズとローカライズ
グローバリゼーションの場合、Blazor から数値と日付の書式設定が提供されます。 ローカライズの場合、Blazor により .NET リソース システムを使用したコンテンツのレンダリングが行われます。
サポートされている ASP.NET Core のローカライズ機能は限られています。
サポート対象: IStringLocalizer と IStringLocalizer<T> は Blazor アプリでサポートされています。
サポート対象外: IHtmlLocalizer、IViewLocalizer、およびデータ注釈のローカライズは ASP.NET Core MVC の機能であり、Blazor アプリでは "サポートされていません"。
この記事では、次に基づいて Blazor のグローバリゼーションとローカライズ機能を使用する方法について説明します。
- ブラウザーの設定でのユーザー言語設定に基づきブラウザーによって設定された
Accept-Language
ヘッダー。 Accept-Language
ヘッダーの値に基づいていない、アプリによって設定されたカルチャ。 設定は、すべてのユーザーに対して静的にするか、アプリ ロジックに基づいて動的にすることができます。 設定がユーザー設定に基づく場合、通常は今後のアクセス時に再読み込みするために設定が保存されます。
全般的な追加情報については、次のリソースを参照してください。
多くの場合、グローバリゼーションとローカライズの概念を扱う場合、''言語'' と ''カルチャ'' という用語は区別なく使用されます。
この記事の場合、言語とは、ユーザーがブラウザーの設定で行った選択を指します。 ユーザーの言語選択は、Accept-Language
ヘッダーのブラウザー要求で送信されます。 ブラウザーの設定では、通常、UI で「言語」という単語が使用されます。
カルチャは、.NET と Blazor API のメンバーに関連します。 たとえば、ユーザーの要求には、ユーザーの観点から言語を指定する Accept-Language
ヘッダーを含めることができますが、アプリでは最終的に、ユーザーが要求した言語から CurrentCulture (「カルチャ」) プロパティが設定されます。 API では通常、メンバー名に "culture" という単語が使用されます。
この記事のガイダンスでは、アクセシビリティ ツールで使用されるページの HTML 言語属性 (<html lang="...">
) の設定については説明しません。 <html>
タグの lang
属性または JavaScript の document.documentElement.lang
に言語を割り当てることで、値を静的に設定できます。 JS 相互運用を使用して document.documentElement.lang
の値を動的に設定できます。
Note
この記事のコード例では、null 許容参照型 (NRT) と .NET コンパイラの null 状態スタティック分析を採用しています。これは、.NET 6 以降の ASP.NET Core でサポートされています。 ASP.NET Core 5.0 以前をターゲットとする場合は、この記事の例から null 型の指定 (?
) を削除してください。
グローバリゼーション
@bind
属性ディレクティブでは、アプリによってサポートされるユーザーの第一優先言語に基づいて形式を適用し、表示向けの値を解析します。 @bind
では、値の解析および書式設定のための System.Globalization.CultureInfo を提供する @bind:culture
パラメーターをサポートしています。
現在のカルチャは、System.Globalization.CultureInfo.CurrentCulture プロパティからアクセスできます。
CultureInfo.InvariantCulture は、次のフィールド型 ({TYPE}
プレースホルダーが型の <input type="{TYPE}" />
) に使用されます。
date
number
前のフィールドの型は次のようになります。
- 適切なブラウザー ベースの書式ルールを使用して表示されます。
- 自由形式のテキストを含めることはできません。
- ブラウザーの実装に基づいてユーザー操作の特性を指定します。
Blazor には、現在のカルチャで値をレンダリングするための組み込みのサポートが用意されています。 したがって、date
と number
フィールドタイプを使用する場合、@bind:culture
でカルチャを指定しないことをお勧めします。
次のフィールドの型には、特定の書式設定の要件がありますが、すべての主要なブラウザーでサポートされていないため、Blazor では現在サポートされていません。
datetime-local
month
week
前述の型の現在のブラウザー サポートについては、使用可能なものに関するページを参照してください。
.NET グローバリゼーションと International Components for Unicode (ICU) のサポート (Blazor WebAssembly)
Blazor WebAssembly は、縮小されたグローバリゼーション API と組み込みの International Components for Unicode (ICU) ロケールのセットを使います。 詳細については、「.NET グローバリゼーションと ICU: WebAssembly での ICU」を参照してください。
カスタム ICU データ ファイルを読み込んでアプリのロケールを制御するには、「WASM グローバリゼーション Icu」を参照してください。 現在は、カスタム ICU データ ファイルを手動で構築する必要があります。 このファイルの作成プロセスを簡単にする .NET ツールは、2024 年 11 月の .NET 9 で予定されています。
Blazor WebAssembly は、縮小されたグローバリゼーション API と組み込みの International Components for Unicode (ICU) ロケールのセットを使います。 詳細については、「.NET グローバリゼーションと ICU: WebAssembly での ICU」を参照してください。
Blazor WebAssembly アプリでロケールのカスタム サブセットを読み込むことは、.NET 8 以降でサポートされています。 詳細については、この記事の 8.0 以降のバージョンに関するセクションにアクセスしてください。
インバリアント グローバリゼーション
このセクションは、クライアント側の Blazor シナリオにのみ適用されます。
アプリのローカライズを必要としない場合は、一般的に英語 (米国) (en-US
) に基づくインバリアント カルチャをサポートするようにアプリを構成します。 インバリアント グローバリゼーションを使用すると、アプリのダウンロード サイズが小さくなり、アプリの起動が高速化されます。 アプリのプロジェクト ファイル (.csproj
) で InvariantGlobalization
プロパティを true
に設定します。
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
または、次の方法でインバリアント グローバリゼーションを構成します。
runtimeconfig.json
の場合:{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }
環境変数を使用:
- キー:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
- 値:
true
または1
- キー:
詳細については、「グローバリゼーションのランタイム構成オプション」 (.NET ドキュメント) を参照してください。
タイムゾーン情報
このセクションは、クライアント側の Blazor シナリオにのみ適用されます。
インバリアント グローバリゼーション を採用すると、ローカライズされていないタイムゾーン名のみが使用されることになります。 タイムゾーン コードとデータをトリミングしてアプリのダウンロード サイズを削減し、アプリの起動を高速化するには、アプリのプロジェクト ファイルで、true
の値を持つ <InvariantTimezone>
MSBuild プロパティを適用します。
<PropertyGroup>
<InvariantTimezone>true</InvariantTimezone>
</PropertyGroup>
Note
<BlazorEnableTimeZoneSupport>
は、以前の <InvariantTimezone>
設定をオーバーライドします。 <BlazorEnableTimeZoneSupport>
設定は削除することをお勧めします。
データ ファイルは、タイムゾーン情報を正しく保つために含まれています。 アプリでこの機能を必要としない場合は、アプリのプロジェクト ファイル内の <BlazorEnableTimeZoneSupport>
MSBuild プロパティを false
に設定して無効にすることを検討してください。
<PropertyGroup>
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
</PropertyGroup>
デモンストレーション コンポーネント
次の CultureExample1
コンポーネントを使用して、この記事で説明する Blazor のグローバリゼーションとローカライズの概念を示せます。
CultureExample1.razor
:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
前の例 (.ToString("N2")
) の数値文字列形式 (N2
) は、標準の .NET 数値書式指定子です。 この N2
形式は、すべての数値型でサポートされ、グループ区切り記号を含み、小数点以下 2 桁まで表示されます。
必要に応じて、CultureExample1
コンポーネントの NavMenu
コンポーネント (NavMenu.razor
) のナビゲーションにメニュー項目を追加します。
Accept-Language
ヘッダーからカルチャを動的に設定する
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Accept-Language
ヘッダーはブラウザーによって設定され、ブラウザー設定でのユーザーの言語設定によって制御されます。 ブラウザー設定では、ユーザーは優先順に 1 つ以上の優先言語を設定します。 設定の順序は、ヘッダー内の言語ごとに品質値 (q
、0-1) を設定するためにブラウザーによって使用されます。 次の例では、英語 (米国) または英語を優先して、英語 (米国)、英語、およびスペイン語 (コスタリカ) を指定しています。
Accept-Language: en-US,en;q=0.9,es-CR;q=0.8
アプリのカルチャは、アプリのサポートされているカルチャに一致する最初に要求された言語を照合することで設定されます。
"クライアント側の開発" では、クライアント側アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
"クライアント側の開発" では、Accept-Language
ヘッダーからカルチャを動的に設定することはできません。
メモ
アプリの仕様で、サポートされているカルチャを明示的な一覧に制限する必要がある場合は、この記事の「ユーザー設定によってクライアント側のカルチャを動的に設定する」セクションを参照してください。
アプリはローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
サービスが追加される Program
ファイルに次の行を追加します。
builder.Services.AddLocalization();
サーバー側の開発では要求カルチャをチェックするミドルウェアの前に、アプリでサポートされているカルチャを指定します。 一般に、 MapRazorComponentsを呼び出す直前に、要求ローカリゼーション ミドルウェアを配置します。 次の例では、英語 (米国) とスペイン語 (コスタリカ) でサポートされるカルチャを構成しています。
サーバー側の開発ではルーティング ミドルウェア (UseRouting) が処理パイプラインに追加された直後に、アプリでサポートされているカルチャを指定します。 次の例では、英語 (米国) とスペイン語 (コスタリカ) でサポートされるカルチャを構成しています。
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CR" })
.AddSupportedUICultures(new[] { "en-US", "es-CR" }));
Program
ファイルのミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (コスタリカ) (es-CR
) に切り替えます。 Web ページを再度要求します。
Note
一部のブラウザーでは、要求とブラウザー独自の UI 設定の両方に既定の言語設定を使用する必要があります。 これにより、すべての設定 UI 画面が読むことができない言語になる可能性があるため、理解できる言語に戻すのが困難になる可能性があります。 Opera などのブラウザーは、Web ページ要求に既定の言語を設定しても、ブラウザーの設定 UI は使用言語のままにしてよいため、テストに最適です。
カルチャが英語 (米国) (en-US
) の場合、表示されるコンポーネントでは、月/日の日付書式設定 (6/7
)、12 時間制の時刻 (AM
/PM
)、および数値でコンマ、小数点値で点の区切り記号 (1,999.69
) が使用されます。
- 日付: 6/7/2021 6:45:22 AM
- 数値: 1,999.69
カルチャがスペイン語 (コスタリカ) (es-CR
) の場合、レンダリングされるコンポーネントでは、日/月の日付書式設定 (7/6
)、24 時間制の時刻、および数値でピリオド、小数点値でコンマの区切り記号 (1.999,69
) が使用されます。
- 日付: 7/6/2021 6:49:38
- 数値: 1.999,69
クライアント側のカルチャを静的に設定する
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
クライアント側のレンダリングに対する中間言語 (IL) リンカーの構成によって、明示的に要求されたロケールを除き、国際化情報が削除されます。 詳しくは、「ASP.NET Core Blazor 用のリンカーを構成する」をご覧ください。
アプリのカルチャは、Blazor が applicationCulture
Blazor スタート オプションで始まるときに JavaScript で設定できます。 次の例では、英語 (米国) (en-US
) カルチャを使用して構成しています。
Blazor の <script>
タグに autostart="false"
を追加して Blazor の自動開始を防止します。
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
前の例の {BLAZOR SCRIPT}
プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。
Blazor の <script>
タグの後、</body>
終了タグの前に、次の <script>
ブロックを追加します。
Blazor Web App:
<script>
Blazor.start({
webAssembly: {
applicationCulture: 'en-US'
}
});
</script>
スタンドアロン Blazor WebAssembly:
<script>
Blazor.start({
applicationCulture: 'en-US'
});
</script>
applicationCulture
の値は、BCP-47 言語タグ形式に準拠している必要があります。 Blazor の起動について詳しくは、「ASP.NET Core Blazor の起動」をご覧ください。
カルチャ Blazor のスタート オプションを設定する代わりに、C# コードでカルチャを設定することもできます。 Program
ファイルの CultureInfo.DefaultThreadCurrentCulture と CultureInfo.DefaultThreadCurrentUICulture を同じカルチャに設定します。
System.Globalization 名前空間を Program
ファイルに追加します。
using System.Globalization;
WebAssemblyHostBuilder (await builder.Build().RunAsync();
) をビルドして実行する行の前にカルチャ設定を追加します。
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
Note
現在、 Blazor WebAssembly アプリは DefaultThreadCurrentCulture に基づいてリソースのみを読み込みます。 詳細については、Blazor WASM が現在のカルチャのみに依存する (現在の UI カルチャは尊重されない) (dotnet/aspnetcore
#56824) に関する記事をご覧ください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (コスタリカ) (es-CR
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (コスタリカ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
サーバー側のカルチャを静的に設定する
サーバー側のアプリはローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program
ファイルで次のように指定します。
builder.Services.AddLocalization();
要求カルチャを確認する可能性のあるミドルウェアの前に、 Program
ファイルで静的カルチャを指定します。 一般に、要求ローカリゼーション ミドルウェアは、 MapRazorComponentsの直前に配置します。 次の例では、英語 (米国) を構成しています。
ルーティング ミドルウェア (UseRouting) が処理パイプラインに追加された直後に、Program
ファイルに静的カルチャを指定します。 次の例では、英語 (米国) を構成しています。
app.UseRequestLocalization("en-US");
UseRequestLocalization のカルチャ値は、BCP-47 言語タグ形式に準拠している必要があります。
Program
ファイルのミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
サーバー側のアプリはローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
(Startup.cs
) で静的カルチャを指定します。 次の例では、英語 (米国) を構成しています。
app.UseRequestLocalization("en-US");
UseRequestLocalization のカルチャ値は、BCP-47 言語タグ形式に準拠している必要があります。
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (コスタリカ) (es-CR
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (コスタリカ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
ユーザー設定によってクライアント側のカルチャを動的に設定する
アプリでユーザーの設定が格納される可能性がある場所の例としては、ブラウザーのローカル ストレージ (クライアント側のシナリオで一般的)、ローカライズ用の cookie またはデータベース (サーバー側のシナリオで一般的)、外部データベースに接続され、Web API によってアクセスされる外部サービスがあります。 次の例は、ブラウザーのローカル ストレージを使用する方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
プロジェクト ファイルで BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
クライアント側レンダリング用のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャの選択は、ブラウザーのローカル ストレージに保存できます。
Blazor の <script>
タグの後に JS 関数を指定して、ユーザーが選択したカルチャをブラウザーのローカル ストレージで取得および設定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Note
前の例では、クライアントがグローバル関数で汚染されます。 実稼働アプリでのより適切なアプローチについては、「JavaScript モジュール内の JavaScript 分離」を参照してください。
System.Globalization と Microsoft.JSInterop の名前空間を、Program
ファイルの先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Note
現在、 Blazor WebAssembly アプリは DefaultThreadCurrentCulture に基づいてリソースのみを読み込みます。 詳細については、Blazor WASM が現在のカルチャのみに依存する (現在の UI カルチャは尊重されない) (dotnet/aspnetcore
#56824) に関する記事をご覧ください。
次の CultureSelector
コンポーネントは、次の操作を実行する方法を示しています。
- JS 相互運用を使用して、ユーザーが選択したカルチャをブラウザーのローカル ストレージに設定します。
- 更新されたカルチャを使用する、要求したコンポーネント (
forceLoad: true
) を再読み込みします。
CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
MainLayout
コンポーネント (MainLayout.razor
) の </main>
要素の終了タグ内に、CultureSelector
コンポーネントを追加します。
<article class="bottom-row px-4">
<CultureSelector />
</article>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
ユーザー設定によってサーバー側のカルチャを動的に設定する
アプリでユーザーの設定が格納される可能性がある場所の例としては、ブラウザーのローカル ストレージ (クライアント側のシナリオで一般的)、ローカライズ用の cookie またはデータベース (サーバー側のシナリオで一般的)、外部データベースに接続され、Web API によってアクセスされる外部サービスがあります。 以下の例では、ローカライズ cookie の使用方法を示しています。
Note
次の例では、App
コンポーネント (Components/App.razor
) の Routes
コンポーネントで対話型サーバー側レンダリング (対話型 SSR) を指定することで、アプリで "グローバル" インタラクティビティが採用されていることを前提としています。
<Routes @rendermode="InteractiveServer" />
アプリでページ/コンポーネント単位のインタラクティビティが採用されている場合、このセクションの終わりにある注釈を見て、例のコンポーネントのレンダー モードを変更してください。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
サーバー側のアプリはローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program
ファイルで次のように指定します。
builder.Services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
要求処理パイプラインで MapRazorComponents を呼び出す前に、次のコードを置換します。
ルーティング ミドルウェア (UseRouting) が要求処理パイプラインに追加されたら、次のコードを配置します。
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
ミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
App
コンポーネントには次の名前空間が必要です。
App
コンポーネント ファイル (Components/App.razor
) の先頭に次を追加します。
@using System.Globalization
@using Microsoft.AspNetCore.Localization
App
コンポーネント ファイルの末尾に次の @code
ブロックを追加します。
@code {
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
Pages/_Host.cshtml
ファイルを変更するには、次の名前空間が必要です。
ファイルに次のコードを追加します。
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
ミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリがコントローラー アクションを処理するように構成されていない場合:
Program
ファイルでサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。builder.Services.AddControllers();
IEndpointRouteBuilder (
app
) で MapControllers を呼び出し、Program
ファイルにコントローラー エンドポイント ルーティングを追加します。app.MapControllers();
ユーザーがカルチャを選択できるように UI を提供するには、ローカライズ cookie でのリダイレクト ベースのアプローチをお勧めします。 アプリでは、コントローラーへのリダイレクトによって、ユーザーが選択したカルチャが保持されます。 コントローラーによって、ユーザーが選択したカルチャが cookie に設定され、ユーザーは元の URI にリダイレクトされます。 このプロセスは、ユーザーがセキュリティで保護されたリソースにアクセスしようとしたときに、Web アプリで発生する処理に似ています。ユーザーがサインイン ページにリダイレクトされ、元のリソースに戻されます。
Controllers/CultureController.cs
:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
警告
前の例に示すように、LocalRedirect アクションの結果を使って、オープン リダイレクト攻撃を防ぎます。 詳細については、「ASP.NET Core でオープン リダイレクト攻撃を防止する」を参照してください。
次の CultureSelector
コンポーネントは、新しいカルチャで CultureController
の Set
メソッドを呼び出す方法を示しています。 コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
MainLayout
コンポーネントに CultureSelector
コンポーネントを追加します。 Components/Layout/MainLayout.razor
ファイルの終了 </main>
タグの中に次のマークアップを配置します。
MainLayout
コンポーネントに CultureSelector
コンポーネントを追加します。 Shared/MainLayout.razor
ファイルの終了 </main>
タグの中に次のマークアップを配置します。
<article class="bottom-row px-4">
<CultureSelector />
</article>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
前の例では、App
コンポーネント (Components/App.razor
) の Routes
コンポーネントで対話型サーバー レンダー モードを指定することで、アプリで "グローバル" インタラクティビティが採用されていることを前提としています。
<Routes @rendermode="InteractiveServer" />
アプリでページ/コンポーネント単位のインタラクティビティが採用されている場合、次の変更を行います。
CultureExample1
コンポーネント ファイル (Components/Pages/CultureExample1.razor
) の先頭に対話型サーバー レンダリング モードを追加します。@rendermode InteractiveServer
アプリのメイン レイアウト (
Components/Layout/MainLayout.razor
) で、CultureSelector
コンポーネントに対話型サーバー レンダリング モードを適用します。<CultureSelector @rendermode="InteractiveServer" />
ユーザー設定に応じて、Blazor Web App にカルチャを動的に設定する
このセクションは、自動 (サーバーおよび WebAssembly) 対話機能を採用する Blazor Web App に適用されます。
アプリでユーザーの設定を保存する場所の例として、ブラウザーのローカル ストレージ (クライアント側のシナリオで一般的)、ローカライズ cookie またはデータベース (サーバー側のシナリオで一般的)、ローカル ストレージとローカライズ cookie (サーバーと WebAssembly コンポーネントを備えたBlazor Web App)、または外部データベースにアタッチされ、Web API からアクセスされる外部サービスがあります。 次の例は、クライアント側レンダリング (CSR) コンポーネントにブラウザーのローカル ストレージを使い、サーバー側でレンダリング (SSR) コンポーネントにローカライズ cookie を使う方法を示しています。
.Client
プロジェクトの更新
Microsoft.Extensions.Localization
パッケージを .Client
プロジェクトに追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
.Client
プロジェクト ファイルで BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
System.Globalization と Microsoft.JSInterop の名前空間を、.Client
プロジェクトの Program
ファイルの先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Note
現在、 Blazor WebAssembly アプリは DefaultThreadCurrentCulture に基づいてリソースのみを読み込みます。 詳細については、Blazor WASM が現在のカルチャのみに依存する (現在の UI カルチャは尊重されない) (dotnet/aspnetcore
#56824) に関する記事をご覧ください。
次の CultureSelector
コンポーネントを .Client
プロジェクトに追加します。
このコンポーネントは、SSR または CSR コンポーネントのいずれかで機能する次のアプローチを採用しています。
- クライアント側のグローバリゼーション データには、サーバー側のグローバリゼーション データが提供するカルチャ表示名のローカライズされたテキストが含まれるため、ドロップダウン リストで使用できる各カルチャの表示名はディクショナリによって提供されます。 たとえば、サーバー側ローカライズには、
en-US
がカルチャである場合はEnglish (United States)
、別のカルチャが使われている場合はIngles ()
が表示されます。 カルチャ表示名のローカライズは Blazor WebAssembly グローバリゼーションでは使用できないため、読み込まれたカルチャに対するクライアント上の米国英語の表示名は単にen-US
になります。 カスタム ディクショナリを使うと、コンポーネントは少なくとも完全な英語のカルチャ名を表示できます。 - ユーザーがカルチャを変更すると、JS 相互運用機能によってローカル ブラウザー ストレージにカルチャが設定され、コントローラー アクションによってそのカルチャでローカライズ cookie が更新されます。 コントローラーは、後述する「サーバー プロジェクトの更新」セクションでアプリに追加されます。
Pages/CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="@selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@cultureDict[culture.Name]</option>
}
</select>
</label>
</p>
@code
{
private Dictionary<string, string> cultureDict =
new()
{
{ "en-US", "English (United States)" },
{ "es-CR", "Spanish (Costa Rica)" }
};
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
.Client
プロジェクトに次の CultureClient
コンポーネントを配置して、CSR コンポーネントのグローバリゼーションがどのように機能するかを調べます。
Pages/CultureClient.razor
:
@page "/culture-client"
@rendermode InteractiveWebAssembly
@using System.Globalization
<PageTitle>Culture Client</PageTitle>
<h1>Culture Client</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
サーバー プロジェクトの更新
サーバー プロジェクトに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
サーバー側のアプリはローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
サービスが登録されているサーバー プロジェクトの Program
ファイル内。
builder.Services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
要求処理パイプラインで MapRazorComponents を呼び出す前に、次のコードを置換します。
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
App
コンポーネントには次の名前空間が必要です。
App
コンポーネント ファイル (Components/App.razor
) の先頭に次を追加します。
@using System.Globalization
@using Microsoft.AspNetCore.Localization
クライアント側レンダリング用のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャ選択は、CSR コンポーネントのブラウザーのローカル ストレージに保存できます。
Blazor の <script>
タグの後に、ブラウザーのローカル ストレージを使ってユーザーのカルチャ選択を取得および設定する JS 関数を指定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Note
前の例では、クライアントがグローバル関数で汚染されます。 実稼働アプリでのより適切なアプローチについては、「JavaScript モジュール内の JavaScript 分離」を参照してください。
App
コンポーネント ファイルの末尾に次の @code
ブロックを追加します。
@code {
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
サーバー プロジェクトがコントローラー アクションを処理するように構成されていない場合:
Program
ファイルでサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。builder.Services.AddControllers();
IEndpointRouteBuilder (
app
) で MapControllers を呼び出し、Program
ファイルにコントローラー エンドポイント ルーティングを追加します。app.MapControllers();
ユーザーが SSR コンポーネントのカルチャを選択できるようにするには、ローカライズ cookie による "リダイレクトベースのアプローチ" を使います。 アプリでは、コントローラーへのリダイレクトによって、ユーザーが選択したカルチャが保持されます。 コントローラーによって、ユーザーが選択したカルチャが cookie に設定され、ユーザーは元の URI にリダイレクトされます。 このプロセスは、ユーザーがセキュリティで保護されたリソースにアクセスしようとしたときに、Web アプリで発生する処理に似ています。ユーザーがサインイン ページにリダイレクトされ、元のリソースに戻されます。
Controllers/CultureController.cs
:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
警告
前の例に示すように、LocalRedirect アクションの結果を使って、オープン リダイレクト攻撃を防ぎます。 詳細については、「ASP.NET Core でオープン リダイレクト攻撃を防止する」を参照してください。
MainLayout
コンポーネントに CultureSelector
コンポーネントを追加します。 Components/Layout/MainLayout.razor
ファイルの終了 </main>
タグの中に次のマークアップを配置します。
<article class="bottom-row px-4">
<CultureSelector @rendermode="InteractiveAuto" />
</article>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
サーバー プロジェクトに次の CultureServer
コンポーネントを配置して、SSR コンポーネントのグローバリゼーションがどのように機能するかを調べます。
Components/Pages/CultureServer.razor
:
@page "/culture-server"
@rendermode InteractiveServer
@using System.Globalization
<PageTitle>Culture Server</PageTitle>
<h1>Culture Server</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
CultureClient
と CultureServer
の両コンポーネントを Components/Layout/NavMenu.razor
のサイドバー ナビゲーションに追加します。
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-server">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Server)
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-client">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Client)
</NavLink>
</div>
対話型自動コンポーネント
このセクションのガイダンスは、対話型自動レンダリング モードを採用するコンポーネントにも適用できます。
@rendermode InteractiveAuto
ローカリゼーション
アプリで動的カルチャの選択がまだサポートされていない場合は、Microsoft.Extensions.Localization
パッケージをアプリに追加します。
メモ
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
クライアント側のローカライズ
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program
ファイルで、System.Globalization の名前空間をファイルの先頭に追加します。
using System.Globalization;
AddLocalization を使用して、アプリのサービスコレクションに Blazor のローカライズ サービスを追加します。
builder.Services.AddLocalization();
サーバー側のローカライズ
ローカライズ ミドルウェアを使用して、アプリのカルチャを設定します。
アプリで動的カルチャの選択がまだサポートされていない場合は、次のようにします。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定のカルチャとサポートされるカルチャを
Program
ファイルで指定します。 次の例では、英語 (米国) とスペイン語 (コスタリカ) でサポートされるカルチャを構成しています。
builder.Services.AddLocalization();
要求カルチャを確認する可能性があるミドルウェアの前に、要求ローカライズ ミドルウェアを配置します。 一般に、ミドルウェアは、 MapRazorComponentsを呼び出す直前に配置します。
ルーティング ミドルウェア (UseRouting) が処理パイプラインに追加された直後:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
ミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定とサポートされるカルチャを
Startup.Configure
(Startup.cs
) で指定します。 次の例では、英語 (米国) とスペイン語 (コスタリカ) でサポートされるカルチャを構成しています。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェア (UseRouting) が処理パイプラインに追加された直後のStartup.Configure
:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリでユーザーのカルチャ設定の格納に基づきリソースをローカライズする必要がある場合は、ローカライズ カルチャ cookie を使用します。 cookie を使用すると、WebSocket 接続によってカルチャを正しく伝達できることを確実にします。 ローカライズ スキームが URL パスまたはクエリ文字列に基づいている場合は、スキームが WebSockets を使用できない可能性があるため、カルチャを保持できません。 したがって、ローカライズ カルチャ cookie の使用をお勧めします。 この記事の「ユーザー設定によってサーバー側のカルチャを動的に設定する」セクションを参照して、ユーザーが選択したカルチャを保持する Razor 式の例を参照してください。
ローカライズされたリソースの例
このセクションのローカライズされたリソースの例は、この記事の前の例と連動しています。アプリのサポートされているカルチャは、既定のロケールとして英語 (en
)、ユーザー選択可能またはブラウザー指定の代替ロケールとしてスペイン語 (es
) になっています。
それぞれのロケールごとのリソース ファイルを作成します。 次の例では、英語とスペイン語の Greeting
文字列のリソースが作成されます。
- 英語 (
en
):Hello, World!
- スペイン語 (
es
):¡Hola, Mundo!
Note
Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択することで、次のリソース ファイルを Visual Studio に追加できます。 そのファイルに CultureExample2.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を Hello, World!
に設定します。 ファイルを保存します。
Visual Studio Code を使用している場合は、Tim Heuer の ResX Viewer and Editor をインストールすることをお勧めします。 Pages
フォルダーに空の CultureExample2.resx
ファイルを追加します。 この拡張機能は、UI でファイル管理を自動的に引き継ぎます。 [新しいリソースの追加] ボタン選択します。 指示に沿って、Greeting
(キー)、Hello, World!
(値)、None
(コメント) のエントリを追加します。 ファイルを保存します。 ファイルを閉じてから再度開くと、Greeting
リソースが表示されます。
Tim Heuer の ResX Viewer and Editor は Microsoft によって所有または保守管理されておらず、Microsoft サポート契約またはライセンスの対象でもありません。
次に、一般的なリソース ファイルを示します。 Visual Studio の組み込みリソース ファイル エディターや、リソース ファイルの作成および編集を行うための拡張機能を備えた Visual Studio Code など、統合開発環境 (IDE) に組み込まれているツールを使用したくない場合は、手動でリソース ファイルをアプリの Pages
フォルダーに配置することができます。
Pages/CultureExample2.resx
:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>Hello, World!</value>
</data>
</root>
Note
Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択することで、次のリソース ファイルを Visual Studio に追加できます。 そのファイルに CultureExample2.es.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を ¡Hola, Mundo!
に設定します。 ファイルを保存します。
Visual Studio Code を使用している場合は、Tim Heuer の ResX Viewer and Editor をインストールすることをお勧めします。 Pages
フォルダーに空の CultureExample2.resx
ファイルを追加します。 この拡張機能は、UI でファイル管理を自動的に引き継ぎます。 [新しいリソースの追加] ボタン選択します。 指示に沿って、Greeting
(キー)、¡Hola, Mundo!
(値)、None
(コメント) のエントリを追加します。 ファイルを保存します。 ファイルを閉じてから再度開くと、Greeting
リソースが表示されます。
次に、一般的なリソース ファイルを示します。 Visual Studio の組み込みリソース ファイル エディターや、リソース ファイルの作成および編集を行うための拡張機能を備えた Visual Studio Code など、統合開発環境 (IDE) に組み込まれているツールを使用したくない場合は、手動でリソース ファイルをアプリの Pages
フォルダーに配置することができます。
Pages/CultureExample2.es.resx
:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>¡Hola, Mundo!</value>
</data>
</root>
次のコンポーネントは、IStringLocalizer<T> でローカライズされた Greeting
文字列を使用する方法を示しています。 次の例の Razor マークアップ @Loc["Greeting"]
では、前のリソース ファイルで設定されている Greeting
値にキーを付けた文字列をローカライズします。
Microsoft.Extensions.Localization の名前空間をアプリの _Imports.razor
ファイルに追加します。
@using Microsoft.Extensions.Localization
CultureExample2.razor
:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
必要に応じて、CultureExample2
コンポーネントのメニュー項目を NavMenu
コンポーネント (NavMenu.razor
) のナビゲーションに追加します。
WebAssembly カルチャ プロバイダーの参照ソース
Blazor フレームワークによるローカライズの処理方法について詳しくは、ASP.NET Core 参照ソースで WebAssemblyCultureProvider
クラスを参照してください。
注意
通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。
共有リソース
ローカライズ共有リソースを作成するには、次の方法を使用します。
任意のクラス名を持つダミーのクラスを作成します。 次に例を示します。
- アプリは
BlazorSample
名前空間を使用し、ローカライズ資産はBlazorSample.Localization
名前空間を使用します。 - ダミー クラスの名前は
SharedResource
です。 - クラス ファイルは、アプリのルートにある
Localization
フォルダーに配置されます。
Localization/SharedResource.cs
:namespace BlazorSample.Localization; public class SharedResource { }
- アプリは
Embedded resource
のビルド アクションを使用して共有リソース ファイルを作成します。 次に例を示します。ファイルは、ダミー
SharedResource
クラス (Localization/SharedResource.cs
) によりLocalization
フォルダーに配置されます。ダミー クラスの名前と一致するようにリソース ファイルに名前を付けます。 次のサンプル ファイルには、既定のローカライズ ファイルとスペイン語 (
es
) ローカライズ用のファイルが含まれます。Localization/SharedResource.resx
Localization/SharedResource.es.resx
警告
このセクションのアプローチに従うときは、 LocalizationOptions.ResourcesPath を同時に設定し、IStringLocalizerFactory.Create を使用してリソースを読み込むことはできません。
Razor コンポーネントの挿入された IStringLocalizer<T> のダミー クラスを参照するには、ローカライズ名前空間の
@using
ディレクティブを配置するか、ダミー クラス参照にローカライズ名前空間を含めます。 次の例で以下を実行します。- 最初の例では、
@using
ディレクティブを使用してSharedResource
ダミー クラスのLocalization
名前空間を指定します。 - 2 番目の例では、
SharedResource
ダミー クラスの名前空間を明示的に指定します。
Razor コンポーネントでは、次の "いずれか" の方法を使用します。
@using Localization @inject IStringLocalizer<SharedResource> Loc
@inject IStringLocalizer<Localization.SharedResource> Loc
- 最初の例では、
その他のガイダンスについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」を参照してください。
開発者ツールの [センサー] ウィンドウを使用した場所のオーバーライド
Google Chrome または Microsoft Edge 開発者ツールの [センサー] ペインを使用して場所のオーバーライドを使用すると、フォールバック言語はプリレンダリング後にリセットされます。 テスト時に [センサー] ペインを使用して言語を設定しないでください。 言語はブラウザーの言語設定を使用して設定します。
詳細については、「Blazorローカライズが InteractiveServer で動作しない (dotnet/aspnetcore
#53707)」を参照してください。
その他のリソース
- アプリのベース パスを設定する
- ASP.NET Core のグローバリゼーションおよびローカリゼーション
- .NET アプリケーションのグローバライズとローカライズ
- .resx ファイル内のリソース
- Microsoft 多言語アプリ ツールキット
- ローカリゼーションとジェネリック
InvokeAsync(StateHasChanged)
を呼び出すと、ページが既定のカルチャにフォールバックする (dotnet/aspnetcore #28521)- Blazorローカライズが InteractiveServer で動作しない (
dotnet/aspnetcore
#53707) ([センサー] ウィンドウを使用した場所のオーバーライド)
ASP.NET Core