ASP.NET Core Blazor のグローバリゼーションおよびローカライズ
この記事では、異なるカルチャや言語のユーザーにグローバル化およびローカライズされたコンテンツをレンダリングする方法について説明します。
グローバリゼーションの場合、Blazor から数値と日付の書式設定が提供されます。 ローカライズの場合、Blazor により .NET リソース システムを使用したコンテンツのレンダリングが行われます。
サポートされている ASP.NET Core のローカライズ機能は限られています。
✔️ IStringLocalizer と IStringLocalizer<T> は、Blazor アプリでサポートされています。
❌IHtmlLocalizer、IViewLocalizer、およびデータ注釈のローカライズは ASP.NET Core MVC の機能であり、Blazor アプリでは ''サポートされていません''。
この記事では、次に基づいて Blazor のグローバリゼーションとローカライズ機能を使用する方法について説明します。
- ブラウザーの設定でのユーザー言語設定に基づきブラウザーによって設定された
Accept-Language
ヘッダー。 Accept-Language
ヘッダーの値に基づいていない、アプリによって設定されたカルチャ。 設定は、すべてのユーザーに対して静的にするか、アプリ ロジックに基づいて動的にすることができます。 設定がユーザー設定に基づく場合、通常は今後のアクセス時に再読み込みするために設定が保存されます。
全般的な追加情報については、次のリソースを参照してください。
Note
多くの場合、グローバリゼーションとローカライズの概念を扱う場合、''言語'' と ''カルチャ'' という用語は区別なく使用されます。
この記事の場合、言語とは、ユーザーがブラウザーの設定で行った選択を指します。 ユーザーの言語選択は、Accept-Language
ヘッダーのブラウザー要求で送信されます。 ブラウザーの設定では、通常、UI で「言語」という単語が使用されます。
カルチャは、.NET と Blazor API のメンバーに関連します。 たとえば、ユーザーの要求には、ユーザーの観点から言語を指定する Accept-Language
ヘッダーを含めることができますが、アプリでは最終的に、ユーザーが要求した言語から CurrentCulture (「カルチャ」) プロパティが設定されます。 API では通常、メンバー名に "culture" という単語が使用されます。
グローバリゼーション
@bind
属性ディレクティブでは、アプリによってサポートされるユーザーの第一優先言語に基づいて形式を適用し、表示向けの値を解析します。 @bind
では、値の解析および書式設定のための System.Globalization.CultureInfo を提供する @bind:culture
パラメーターをサポートしています。
現在のカルチャは、System.Globalization.CultureInfo.CurrentCulture プロパティからアクセスできます。
CultureInfo.InvariantCulture は、次のフィールド型 ({TYPE}
プレースホルダーが型の <input type="{TYPE}" />
) に使用されます。
date
number
前のフィールドの型は次のようになります。
- 適切なブラウザー ベースの書式ルールを使用して表示されます。
- 自由形式のテキストを含めることはできません。
- ブラウザーの実装に基づいてユーザー操作の特性を指定します。
date
と number
フィールド型を使用する場合、Blazor から現在のカルチャの値をレンダリングするサポートが組み込みで提供されるため、@bind:culture
でカルチャを指定することはお勧めしません。
次のフィールドの型には、特定の書式設定の要件がありますが、すべての主要なブラウザーでサポートされていないため、Blazor では現在サポートされていません。
datetime-local
month
week
前述の型の現在のブラウザー サポートについては、使用可能なものに関するページを参照してください。
インバリアント グローバリゼーション
アプリのローカライズを必要としない場合は、一般的に英語 (米国) (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 ドキュメント) を参照してください。
デモンストレーション コンポーネント
次の CultureExample1
コンポーネントを使用して、この記事で説明する Blazor のグローバリゼーションとローカライズの概念を示せます。
Pages/CultureExample1.razor
:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<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
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
Accept-Language
ヘッダーからカルチャを動的に設定する
Accept-Language
ヘッダーはブラウザーによって設定され、ブラウザー設定でのユーザーの言語設定によって制御されます。 ブラウザー設定では、ユーザーは優先順に 1 つ以上の優先言語を設定します。 設定の順序は、ヘッダー内の言語ごとに品質値 (q
、0-1) を設定するためにブラウザーによって使用されます。 次の例では、英語 (米国) または英語を優先して、英語 (米国)、英語、およびスペイン語 (チリ) を指定しています。
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
アプリのカルチャは、アプリのサポートされているカルチャに一致する最初に要求された言語を照合することで設定されます。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Note
アプリの仕様で、サポートされているカルチャを明示的な一覧に制限する必要がある場合は、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照してください。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
でアプリでサポートされているカルチャを指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 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-CL
) の場合、レンダリングされるコンポーネントでは、日/月の日付書式設定 (7/6
)、24 時間制の時刻、および数値でピリオド、小数点値でコンマの区切り記号 (1.999,69
) が使用されます。
- 日付: 7/6/2021 6:49:38
- 数値: 1.999,69
カルチャを静的に設定する
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
アプリのカルチャは、Blazor が applicationCulture
Blazor スタート オプションで始まるときに JavaScript で設定できます。 次の例では、英語 (米国) (en-US
) カルチャを使用して構成しています。
wwwroot/index.html
では、Blazor の<script>
タグにautostart="false"
を追加して Blazor 自動開始を防止します。<script src="_framework/blazor.webassembly.js" autostart="false"></script>
Blazor の
<script>
タグの後、</body>
終了タグの前に、次の<script>
ブロックを追加します。<script> Blazor.start({ applicationCulture: 'en-US' }); </script>
applicationCulture
の値は、BCP-47 言語タグ形式に準拠している必要があります。 Blazor の起動について詳しくは、「ASP.NET Core Blazor の起動」をご覧ください。
カルチャ Blazor のスタート オプションを設定する代わりに、C# コードでカルチャを設定することもできます。 Program.cs
の CultureInfo.DefaultThreadCurrentCulture と CultureInfo.DefaultThreadCurrentUICulture を同じカルチャに設定します。
System.Globalization 名前空間を Program.cs
に追加します。
using System.Globalization;
WebAssemblyHostBuilder (await builder.Build().RunAsync();
) をビルドして実行する行の前にカルチャ設定を追加します。
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で静的カルチャを指定します。 次の例では、英語 (米国) を構成しています。
app.UseRequestLocalization("en-US");
UseRequestLocalization のカルチャ値は、BCP-47 言語タグ形式に準拠している必要があります。
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (チリ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
ユーザー設定によってカルチャを動的に設定する
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 次の例は、ブラウザーのローカル ストレージを使用する方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
プロジェクト ファイルで BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor WebAssembly アプリ内のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャの選択は、ブラウザーのローカル ストレージに保存できます。
wwwroot/index.html
ファイルの Blazor の <script>
タグの後、かつ </body>
終了タグの前に、JS 関数を指定して、ユーザーが選択したカルチャをブラウザーのローカル ストレージで取得および設定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Note
前の例ではグローバル メソッドでクライアントが汚染されます。 実稼働アプリでのより適切なアプローチについては、「JavaScript モジュール内の JavaScript 分離」を参照してください。
System.Globalization と Microsoft.JSInterop の名前空間を Program.cs
の先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
Program.cs
から次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
次の CultureSelector
コンポーネントは、次の操作を実行する方法を示しています。
- JS 相互運用を使用して、ユーザーが選択したカルチャをブラウザーのローカル ストレージに設定します。
- 更新されたカルチャを使用する、要求したコンポーネント (
forceLoad: true
) を再読み込みします。
CultureSelector
コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
Shared/MainLayout.razor
の </main>
要素の終了タグ内に、CultureSelector
コンポーネントを追加します。
<article class="bottom-row px-4">
<CultureSelector />
</article>
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 以下の例では、ローカライズ cookie の使用方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
Pages/_Host.cshtml
ファイルを変更するには、次の名前空間が必要です。
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)));
+ }
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリがコントローラー アクションを処理するように構成されていない場合:
Program.cs
でサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。builder.Services.AddControllers();
IEndpointRouteBuilder で MapControllers を呼び出し、
Program.cs
でコントローラー エンドポイント ルーティングを追加します。app.MapControllers();
次の例は、行が追加された後の UseEndpoints への呼び出しを示しています。
app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host");
ユーザーがカルチャを選択できるように 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
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor
の </main>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<article class="bottom-row px-4">
<CultureSelector />
</article>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
ローカライズ
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションに従って、カルチャの選択をまだサポートしていない場合は、アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program.cs
で、System.Globalization の名前空間をファイルの先頭に追加します。
using System.Globalization;
Program.cs
の AddLocalization を使用して、アプリのサービスコレクションに Blazor のローカライズ サービスを追加します。
builder.Services.AddLocalization();
ローカライズ ミドルウェアを使用して、アプリのカルチャを設定します。
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」に従って、カルチャの選択をまだサポートしていない場合は、次の手順を実行します。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定とサポートされるカルチャを
Program.cs
で指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリでユーザーのカルチャ設定の格納に基づきリソースをローカライズする必要がある場合は、ローカライズ カルチャ cookie を使用します。 cookie を使用すると、WebSocket 接続によってカルチャを正しく伝達できることを確実にします。 ローカライズ スキームが URL パスまたはクエリ文字列に基づいている場合は、スキームが WebSockets を使用できない可能性があるため、カルチャを保持できません。 したがって、ローカライズ カルチャ cookie の使用をお勧めします。 この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照して、ユーザーが選択したカルチャを保持する Razor 式の例を参照してください。
このセクションのローカライズされたリソースの例は、この記事の前の例と連動しています。アプリのサポートされているカルチャは、既定のロケールとして英語 (en
)、ユーザー選択可能またはブラウザー指定の代替ロケールとしてスペイン語 (es
) になっています。
ロケールごとにリソースを作成します。 次の例では、既定の Greeting
文字列のリソースが作成されます。
- 英語:
Hello, World!
- スペイン語 (
es
):¡Hola, Mundo!
Note
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を Hello, World!
に設定します。 ファイルを保存します。
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>
注意
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.es.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を ¡Hola, Mundo!
に設定します。 ファイルを保存します。
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
Pages/CultureExample2.razor
:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
必要に応じて、CultureExample2
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
カルチャ プロバイダーの参照ソース
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
Note
Localization
は、LocalizationOptions を介して設定することができるリソース パスです。Razor コンポーネントの挿入された IStringLocalizer<T> のダミー クラスを参照するには、ローカライズ名前空間の
@using
ディレクティブを配置するか、ダミー クラス参照にローカライズ名前空間を含めます。 次の例で以下を実行します。- 最初の例では、
@using
ディレクティブを使用してSharedResource
ダミー クラスのLocalization
名前空間を指定します。 - 2 番目の例では、
SharedResource
ダミー クラスの名前空間を明示的に指定します。
Razor コンポーネントでは、次の "いずれか" の方法を使用します。
@using Localization @inject IStringLocalizer<SharedResource> Loc
@inject IStringLocalizer<Localization.SharedResource> Loc
- 最初の例では、
その他のガイダンスについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」を参照してください。
その他の技術情報
グローバリゼーションの場合、Blazor から数値と日付の書式設定が提供されます。 ローカライズの場合、Blazor により .NET リソース システムを使用したコンテンツのレンダリングが行われます。
サポートされている ASP.NET Core のローカライズ機能は限られています。
✔️ IStringLocalizer と IStringLocalizer<T> は、Blazor アプリでサポートされています。
❌IHtmlLocalizer、IViewLocalizer、およびデータ注釈のローカライズは ASP.NET Core MVC の機能であり、Blazor アプリでは ''サポートされていません''。
この記事では、次に基づいて Blazor のグローバリゼーションとローカライズ機能を使用する方法について説明します。
- ブラウザーの設定でのユーザー言語設定に基づきブラウザーによって設定された
Accept-Language
ヘッダー。 Accept-Language
ヘッダーの値に基づいていない、アプリによって設定されたカルチャ。 設定は、すべてのユーザーに対して静的にするか、アプリ ロジックに基づいて動的にすることができます。 設定がユーザー設定に基づく場合、通常は今後のアクセス時に再読み込みするために設定が保存されます。
全般的な追加情報については、次のリソースを参照してください。
Note
多くの場合、グローバリゼーションとローカライズの概念を扱う場合、''言語'' と ''カルチャ'' という用語は区別なく使用されます。
この記事の場合、言語とは、ユーザーがブラウザーの設定で行った選択を指します。 ユーザーの言語選択は、Accept-Language
ヘッダーのブラウザー要求で送信されます。 ブラウザーの設定では、通常、UI で「言語」という単語が使用されます。
カルチャは、.NET と Blazor API のメンバーに関連します。 たとえば、ユーザーの要求には、ユーザーの観点から言語を指定する Accept-Language
ヘッダーを含めることができますが、アプリでは最終的に、ユーザーが要求した言語から CurrentCulture (「カルチャ」) プロパティが設定されます。 API では通常、メンバー名に "culture" という単語が使用されます。
グローバリゼーション
@bind
属性ディレクティブでは、アプリによってサポートされるユーザーの第一優先言語に基づいて形式を適用し、表示向けの値を解析します。 @bind
では、値の解析および書式設定のための System.Globalization.CultureInfo を提供する @bind:culture
パラメーターをサポートしています。
現在のカルチャは、System.Globalization.CultureInfo.CurrentCulture プロパティからアクセスできます。
CultureInfo.InvariantCulture は、次のフィールド型 ({TYPE}
プレースホルダーが型の <input type="{TYPE}" />
) に使用されます。
date
number
前のフィールドの型は次のようになります。
- 適切なブラウザー ベースの書式ルールを使用して表示されます。
- 自由形式のテキストを含めることはできません。
- ブラウザーの実装に基づいてユーザー操作の特性を指定します。
date
と number
フィールド型を使用する場合、Blazor から現在のカルチャの値をレンダリングするサポートが組み込みで提供されるため、@bind:culture
でカルチャを指定することはお勧めしません。
次のフィールドの型には、特定の書式設定の要件がありますが、すべての主要なブラウザーでサポートされていないため、Blazor では現在サポートされていません。
datetime-local
month
week
前述の型の現在のブラウザー サポートについては、使用可能なものに関するページを参照してください。
インバリアント グローバリゼーション
アプリのローカライズを必要としない場合は、一般的に英語 (米国) (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 ドキュメント) を参照してください。
デモンストレーション コンポーネント
次の CultureExample1
コンポーネントを使用して、この記事で説明する Blazor のグローバリゼーションとローカライズの概念を示せます。
Pages/CultureExample1.razor
:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<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
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
Accept-Language
ヘッダーからカルチャを動的に設定する
Accept-Language
ヘッダーはブラウザーによって設定され、ブラウザー設定でのユーザーの言語設定によって制御されます。 ブラウザー設定では、ユーザーは優先順に 1 つ以上の優先言語を設定します。 設定の順序は、ヘッダー内の言語ごとに品質値 (q
、0-1) を設定するためにブラウザーによって使用されます。 次の例では、英語 (米国) または英語を優先して、英語 (米国)、英語、およびスペイン語 (チリ) を指定しています。
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
アプリのカルチャは、アプリのサポートされているカルチャに一致する最初に要求された言語を照合することで設定されます。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Note
アプリの仕様で、サポートされているカルチャを明示的な一覧に制限する必要がある場合は、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照してください。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
でアプリでサポートされているカルチャを指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 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-CL
) の場合、レンダリングされるコンポーネントでは、日/月の日付書式設定 (7/6
)、24 時間制の時刻、および数値でピリオド、小数点値でコンマの区切り記号 (1.999,69
) が使用されます。
- 日付: 7/6/2021 6:49:38
- 数値: 1.999,69
カルチャを静的に設定する
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
アプリのカルチャは、Blazor が applicationCulture
Blazor スタート オプションで始まるときに JavaScript で設定できます。 次の例では、英語 (米国) (en-US
) カルチャを使用して構成しています。
wwwroot/index.html
では、Blazor の<script>
タグにautostart="false"
を追加して Blazor 自動開始を防止します。<script src="_framework/blazor.webassembly.js" autostart="false"></script>
Blazor の
<script>
タグの後、</body>
終了タグの前に、次の<script>
ブロックを追加します。<script> Blazor.start({ applicationCulture: 'en-US' }); </script>
applicationCulture
の値は、BCP-47 言語タグ形式に準拠している必要があります。 Blazor の起動について詳しくは、「ASP.NET Core Blazor の起動」をご覧ください。
カルチャ Blazor のスタート オプションを設定する代わりに、C# コードでカルチャを設定することもできます。 Program.cs
の CultureInfo.DefaultThreadCurrentCulture と CultureInfo.DefaultThreadCurrentUICulture を同じカルチャに設定します。
System.Globalization 名前空間を Program.cs
に追加します。
using System.Globalization;
WebAssemblyHostBuilder (await builder.Build().RunAsync();
) をビルドして実行する行の前にカルチャ設定を追加します。
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で静的カルチャを指定します。 次の例では、英語 (米国) を構成しています。
app.UseRequestLocalization("en-US");
UseRequestLocalization のカルチャ値は、BCP-47 言語タグ形式に準拠している必要があります。
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (チリ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
ユーザー設定によってカルチャを動的に設定する
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 次の例は、ブラウザーのローカル ストレージを使用する方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
プロジェクト ファイルで BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor WebAssembly アプリ内のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャの選択は、ブラウザーのローカル ストレージに保存できます。
wwwroot/index.html
ファイルの Blazor の <script>
タグの後、かつ </body>
終了タグの前に、JS 関数を指定して、ユーザーが選択したカルチャをブラウザーのローカル ストレージで取得および設定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Note
前の例ではグローバル メソッドでクライアントが汚染されます。 実稼働アプリでのより適切なアプローチについては、「JavaScript モジュール内の JavaScript 分離」を参照してください。
System.Globalization と Microsoft.JSInterop の名前空間を Program.cs
の先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
Program.cs
から次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
次の CultureSelector
コンポーネントは、次の操作を実行する方法を示しています。
- JS 相互運用を使用して、ユーザーが選択したカルチャをブラウザーのローカル ストレージに設定します。
- 更新されたカルチャを使用する、要求したコンポーネント (
forceLoad: true
) を再読み込みします。
CultureSelector
コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
Shared/MainLayout.razor
の <main>
要素の終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 以下の例では、ローカライズ cookie の使用方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Program.cs
の場合:
builder.Services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
Pages/_Host.cshtml
ファイルを変更するには、次の名前空間が必要です。
Pages/_Host.cshtml
:
@page "/"
@namespace {NAMESPACE}.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
Layout = "_Layout";
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
<component type="typeof(App)" render-mode="ServerPrerendered" />
前の例では、{NAMESPACE}
プレースホルダーはアプリのアセンブリ名です。
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリがコントローラー アクションを処理するように構成されていない場合:
Program.cs
でサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。builder.Services.AddControllers();
IEndpointRouteBuilder で MapControllers を呼び出し、
Program.cs
でコントローラー エンドポイント ルーティングを追加します。app.MapControllers();
次の例は、行が追加された後の UseEndpoints への呼び出しを示しています。
app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host");
ユーザーがカルチャを選択できるように 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
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor
の <main>
要素の </div>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
ローカライズ
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションに従って、カルチャの選択をまだサポートしていない場合は、アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program.cs
で、System.Globalization の名前空間をファイルの先頭に追加します。
using System.Globalization;
Program.cs
の AddLocalization を使用して、アプリのサービスコレクションに Blazor のローカライズ サービスを追加します。
builder.Services.AddLocalization();
ローカライズ ミドルウェアを使用して、アプリのカルチャを設定します。
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」に従って、カルチャの選択をまだサポートしていない場合は、次の手順を実行します。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定とサポートされるカルチャを
Program.cs
で指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
Program.cs
の場合:
builder.Services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Program.cs
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Program.cs
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリでユーザーのカルチャ設定の格納に基づきリソースをローカライズする必要がある場合は、ローカライズ カルチャ cookie を使用します。 cookie を使用すると、WebSocket 接続によってカルチャを正しく伝達できることを確実にします。 ローカライズ スキームが URL パスまたはクエリ文字列に基づいている場合は、スキームが WebSockets を使用できない可能性があるため、カルチャを保持できません。 したがって、ローカライズ カルチャ cookie の使用をお勧めします。 この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照して、ユーザーが選択したカルチャを保持する Razor 式の例を参照してください。
このセクションのローカライズされたリソースの例は、この記事の前の例と連動しています。アプリのサポートされているカルチャは、既定のロケールとして英語 (en
)、ユーザー選択可能またはブラウザー指定の代替ロケールとしてスペイン語 (es
) になっています。
ロケールごとにリソースを作成します。 次の例では、既定の Greeting
文字列のリソースが作成されます。
- 英語:
Hello, World!
- スペイン語 (
es
):¡Hola, Mundo!
Note
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を Hello, World!
に設定します。 ファイルを保存します。
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>
注意
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.es.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を ¡Hola, Mundo!
に設定します。 ファイルを保存します。
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
Pages/CultureExample2.razor
:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
必要に応じて、CultureExample2
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
カルチャ プロバイダーの参照ソース
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
注意
Localization
は、LocalizationOptions を介して設定することができるリソース パスです。Razor コンポーネントの挿入された IStringLocalizer<T> のダミー クラスを参照するには、ローカライズ名前空間の
@using
ディレクティブを配置するか、ダミー クラス参照にローカライズ名前空間を含めます。 次の例で以下を実行します。- 最初の例では、
@using
ディレクティブを使用してSharedResource
ダミー クラスのLocalization
名前空間を指定します。 - 2 番目の例では、
SharedResource
ダミー クラスの名前空間を明示的に指定します。
Razor コンポーネントでは、次の "いずれか" の方法を使用します。
@using Localization @inject IStringLocalizer<SharedResource> Loc
@inject IStringLocalizer<Localization.SharedResource> Loc
- 最初の例では、
その他のガイダンスについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」を参照してください。
その他の技術情報
グローバリゼーションの場合、Blazor から数値と日付の書式設定が提供されます。 ローカライズの場合、Blazor により .NET リソース システムを使用したコンテンツのレンダリングが行われます。
サポートされている ASP.NET Core のローカライズ機能は限られています。
✔️ IStringLocalizer と IStringLocalizer<T> は、Blazor アプリでサポートされています。
❌IHtmlLocalizer、IViewLocalizer、およびデータ注釈のローカライズは ASP.NET Core MVC の機能であり、Blazor アプリでは ''サポートされていません''。
この記事では、次に基づいて Blazor のグローバリゼーションとローカライズ機能を使用する方法について説明します。
- ブラウザーの設定でのユーザー言語設定に基づきブラウザーによって設定された
Accept-Language
ヘッダー。 Accept-Language
ヘッダーの値に基づいていない、アプリによって設定されたカルチャ。 設定は、すべてのユーザーに対して静的にするか、アプリ ロジックに基づいて動的にすることができます。 設定がユーザー設定に基づく場合、通常は今後のアクセス時に再読み込みするために設定が保存されます。
全般的な追加情報については、次のリソースを参照してください。
Note
多くの場合、グローバリゼーションとローカライズの概念を扱う場合、''言語'' と ''カルチャ'' という用語は区別なく使用されます。
この記事の場合、言語とは、ユーザーがブラウザーの設定で行った選択を指します。 ユーザーの言語選択は、Accept-Language
ヘッダーのブラウザー要求で送信されます。 ブラウザーの設定では、通常、UI で「言語」という単語が使用されます。
カルチャは、.NET と Blazor API のメンバーに関連します。 たとえば、ユーザーの要求には、ユーザーの観点から言語を指定する Accept-Language
ヘッダーを含めることができますが、アプリでは最終的に、ユーザーが要求した言語から CurrentCulture (「カルチャ」) プロパティが設定されます。 API では通常、メンバー名に "culture" という単語が使用されます。
グローバリゼーション
@bind
属性ディレクティブでは、アプリによってサポートされるユーザーの第一優先言語に基づいて形式を適用し、表示向けの値を解析します。 @bind
では、値の解析および書式設定のための System.Globalization.CultureInfo を提供する @bind:culture
パラメーターをサポートしています。
現在のカルチャは、System.Globalization.CultureInfo.CurrentCulture プロパティからアクセスできます。
CultureInfo.InvariantCulture は、次のフィールド型 ({TYPE}
プレースホルダーが型の <input type="{TYPE}" />
) に使用されます。
date
number
前のフィールドの型は次のようになります。
- 適切なブラウザー ベースの書式ルールを使用して表示されます。
- 自由形式のテキストを含めることはできません。
- ブラウザーの実装に基づいてユーザー操作の特性を指定します。
date
と number
フィールド型を使用する場合、Blazor から現在のカルチャの値をレンダリングするサポートが組み込みで提供されるため、@bind:culture
でカルチャを指定することはお勧めしません。
次のフィールドの型には、特定の書式設定の要件がありますが、すべての主要なブラウザーでサポートされていないため、Blazor では現在サポートされていません。
datetime-local
month
week
前述の型の現在のブラウザー サポートについては、使用可能なものに関するページを参照してください。
インバリアント グローバリゼーション
アプリのローカライズを必要としない場合は、一般的に英語 (米国) (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 ドキュメント) を参照してください。
デモンストレーション コンポーネント
次の CultureExample1
コンポーネントを使用して、この記事で説明する Blazor のグローバリゼーションとローカライズの概念を示せます。
Pages/CultureExample1.razor
:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<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
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
Accept-Language
ヘッダーからカルチャを動的に設定する
Accept-Language
ヘッダーはブラウザーによって設定され、ブラウザー設定でのユーザーの言語設定によって制御されます。 ブラウザー設定では、ユーザーは優先順に 1 つ以上の優先言語を設定します。 設定の順序は、ヘッダー内の言語ごとに品質値 (q
、0-1) を設定するためにブラウザーによって使用されます。 次の例では、英語 (米国) または英語を優先して、英語 (米国)、英語、およびスペイン語 (チリ) を指定しています。
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
アプリのカルチャは、アプリのサポートされているカルチャに一致する最初に要求された言語を照合することで設定されます。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Note
アプリの仕様で、サポートされているカルチャを明示的な一覧に制限する必要がある場合は、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照してください。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
(Startup.cs
) でアプリでサポートされているカルチャを指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 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-CL
) の場合、レンダリングされるコンポーネントでは、日/月の日付書式設定 (7/6
)、24 時間制の時刻、および数値でピリオド、小数点値でコンマの区切り記号 (1.999,69
) が使用されます。
- 日付: 7/6/2021 6:49:38
- 数値: 1.999,69
カルチャを静的に設定する
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
アプリのカルチャは、Blazor が applicationCulture
Blazor スタート オプションで始まるときに JavaScript で設定できます。 次の例では、英語 (米国) (en-US
) カルチャを使用して構成しています。
wwwroot/index.html
では、Blazor の<script>
タグにautostart="false"
を追加して Blazor 自動開始を防止します。<script src="_framework/blazor.webassembly.js" autostart="false"></script>
Blazor の
<script>
タグの後、</body>
終了タグの前に、次の<script>
ブロックを追加します。<script> Blazor.start({ applicationCulture: 'en-US' }); </script>
applicationCulture
の値は、BCP-47 言語タグ形式に準拠している必要があります。 Blazor の起動について詳しくは、「ASP.NET Core Blazor の起動」をご覧ください。
カルチャ Blazor のスタート オプションを設定する代わりに、C# コードでカルチャを設定することもできます。 Program.cs
の CultureInfo.DefaultThreadCurrentCulture と CultureInfo.DefaultThreadCurrentUICulture を同じカルチャに設定します。
System.Globalization 名前空間を Program.cs
に追加します。
using System.Globalization;
WebAssemblyHostBuilder (await builder.Build().RunAsync();
) をビルドして実行する行の前にカルチャ設定を追加します。
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 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-CL
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (チリ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
ユーザー設定によってカルチャを動的に設定する
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 次の例は、ブラウザーのローカル ストレージを使用する方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
プロジェクト ファイルで BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Blazor WebAssembly アプリ内のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャの選択は、ブラウザーのローカル ストレージに保存できます。
wwwroot/index.html
ファイルの Blazor の <script>
タグの後、かつ </body>
終了タグの前に、JS 関数を指定して、ユーザーが選択したカルチャをブラウザーのローカル ストレージで取得および設定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
注意
前の例ではグローバル メソッドでクライアントが汚染されます。 実稼働アプリでのより適切なアプローチについては、「JavaScript モジュール内の JavaScript 分離」を参照してください。
System.Globalization と Microsoft.JSInterop の名前空間を Program.cs
の先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
Program.cs
から次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
次の CultureSelector
コンポーネントは、JS 相互運用を使用して、ユーザーが選択したカルチャをブラウザーのローカル ストレージに設定する方法を示しています。 コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
Shared/MainLayout.razor
の <div class="main">
要素の </div>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 以下の例では、ローカライズ cookie の使用方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
次の名前空間を Pages/_Host.cshtml
ファイルの先頭に追加します。
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Pages/_Host.cshtml
の <body>
開始タグの直後に、次の Razor 式を追加します。
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリがコントローラー アクションを処理するように構成されていない場合:
Startup.ConfigureServices
でサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。services.AddControllers();
IEndpointRouteBuilder で MapControllers を呼び出し、
Startup.Configure
でコントローラー エンドポイント ルーティングを追加します。endpoints.MapControllers();
次の例は、行が追加された後の UseEndpoints への呼び出しを示しています。
app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
ユーザーがカルチャを選択できるように 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
コンポーネントでは、ユーザーがカルチャを選択したときに、最初のリダイレクトを実行する方法を示しています。 コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor
の <div class="main">
要素の </div>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
ローカライズ
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションに従って、カルチャの選択をまだサポートしていない場合は、アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
アプリのプロジェクト ファイル (.csproj
) で BlazorWebAssemblyLoadAllGlobalizationData
プロパティを true
に設定します。
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Program.cs
で、System.Globalization の名前空間をファイルの先頭に追加します。
using System.Globalization;
Program.cs
の AddLocalization を使用して、アプリのサービスコレクションに Blazor のローカライズ サービスを追加します。
builder.Services.AddLocalization();
ローカライズ ミドルウェアを使用して、アプリのカルチャを設定します。
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」に従って、カルチャの選択をまだサポートしていない場合は、次の手順を実行します。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定とサポートされるカルチャを
Startup.Configure
(Startup.cs
) で指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
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 の使用をお勧めします。 この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照して、ユーザーが選択したカルチャを保持する Pages/_Host.cshtml
ファイルの Razor 式の例を参照してください。
このセクションのローカライズされたリソースの例は、この記事の前の例と連動しています。アプリのサポートされているカルチャは、既定のロケールとして英語 (en
)、ユーザー選択可能またはブラウザー指定の代替ロケールとしてスペイン語 (es
) になっています。
ロケールごとにリソースを作成します。 次の例では、既定の Greeting
文字列のリソースが作成されます。
- 英語:
Hello, World!
- スペイン語 (
es
):¡Hola, Mundo!
Note
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を Hello, World!
に設定します。 ファイルを保存します。
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>
注意
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.es.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を ¡Hola, Mundo!
に設定します。 ファイルを保存します。
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
Pages/CultureExample2.razor
:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
必要に応じて、CultureExample2
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
カルチャ プロバイダーの参照ソース
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
Note
Localization
は、LocalizationOptions を介して設定することができるリソース パスです。Razor コンポーネントの挿入された IStringLocalizer<T> のダミー クラスを参照するには、ローカライズ名前空間の
@using
ディレクティブを配置するか、ダミー クラス参照にローカライズ名前空間を含めます。 次の例で以下を実行します。- 最初の例では、
@using
ディレクティブを使用してSharedResource
ダミー クラスのLocalization
名前空間を指定します。 - 2 番目の例では、
SharedResource
ダミー クラスの名前空間を明示的に指定します。
Razor コンポーネントでは、次の "いずれか" の方法を使用します。
@using Localization @inject IStringLocalizer<SharedResource> Loc
@inject IStringLocalizer<Localization.SharedResource> Loc
- 最初の例では、
その他のガイダンスについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」を参照してください。
その他の技術情報
グローバリゼーションの場合、Blazor から数値と日付の書式設定が提供されます。 ローカライズの場合、Blazor により .NET リソース システムを使用したコンテンツのレンダリングが行われます。
サポートされている ASP.NET Core のローカライズ機能は限られています。
✔️ IStringLocalizer と IStringLocalizer<T> は、Blazor アプリでサポートされています。
❌IHtmlLocalizer、IViewLocalizer、およびデータ注釈のローカライズは ASP.NET Core MVC の機能であり、Blazor アプリでは ''サポートされていません''。
この記事では、次に基づいて Blazor のグローバリゼーションとローカライズ機能を使用する方法について説明します。
- ブラウザーの設定でのユーザー言語設定に基づきブラウザーによって設定された
Accept-Language
ヘッダー。 Accept-Language
ヘッダーの値に基づいていない、アプリによって設定されたカルチャ。 設定は、すべてのユーザーに対して静的にするか、アプリ ロジックに基づいて動的にすることができます。 設定がユーザー設定に基づく場合、通常は今後のアクセス時に再読み込みするために設定が保存されます。
全般的な追加情報については、次のリソースを参照してください。
Note
多くの場合、グローバリゼーションとローカライズの概念を扱う場合、''言語'' と ''カルチャ'' という用語は区別なく使用されます。
この記事の場合、言語とは、ユーザーがブラウザーの設定で行った選択を指します。 ユーザーの言語選択は、Accept-Language
ヘッダーのブラウザー要求で送信されます。 ブラウザーの設定では、通常、UI で「言語」という単語が使用されます。
カルチャは、.NET と Blazor API のメンバーに関連します。 たとえば、ユーザーの要求には、ユーザーの観点から言語を指定する Accept-Language
ヘッダーを含めることができますが、アプリでは最終的に、ユーザーが要求した言語から CurrentCulture (「カルチャ」) プロパティが設定されます。 API では通常、メンバー名に "culture" という単語が使用されます。
グローバリゼーション
@bind
属性ディレクティブでは、アプリによってサポートされるユーザーの第一優先言語に基づいて形式を適用し、表示向けの値を解析します。 @bind
では、値の解析および書式設定のための System.Globalization.CultureInfo を提供する @bind:culture
パラメーターをサポートしています。
現在のカルチャは、System.Globalization.CultureInfo.CurrentCulture プロパティからアクセスできます。
CultureInfo.InvariantCulture は、次のフィールド型 ({TYPE}
プレースホルダーが型の <input type="{TYPE}" />
) に使用されます。
date
number
前のフィールドの型は次のようになります。
- 適切なブラウザー ベースの書式ルールを使用して表示されます。
- 自由形式のテキストを含めることはできません。
- ブラウザーの実装に基づいてユーザー操作の特性を指定します。
date
と number
フィールド型を使用する場合、Blazor から現在のカルチャの値をレンダリングするサポートが組み込みで提供されるため、@bind:culture
でカルチャを指定することはお勧めしません。
次のフィールドの型には、特定の書式設定の要件がありますが、すべての主要なブラウザーでサポートされていないため、Blazor では現在サポートされていません。
datetime-local
month
week
前述の型の現在のブラウザー サポートについては、使用可能なものに関するページを参照してください。
インバリアント グローバリゼーション
アプリのローカライズを必要としない場合は、一般的に英語 (米国) (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 ドキュメント) を参照してください。
デモンストレーション コンポーネント
次の CultureExample1
コンポーネントを使用して、この記事で説明する Blazor のグローバリゼーションとローカライズの概念を示せます。
Pages/CultureExample1.razor
:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<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
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
Accept-Language
ヘッダーからカルチャを動的に設定する
Accept-Language
ヘッダーはブラウザーによって設定され、ブラウザー設定でのユーザーの言語設定によって制御されます。 ブラウザー設定では、ユーザーは優先順に 1 つ以上の優先言語を設定します。 設定の順序は、ヘッダー内の言語ごとに品質値 (q
、0-1) を設定するためにブラウザーによって使用されます。 次の例では、英語 (米国) または英語を優先して、英語 (米国)、英語、およびスペイン語 (チリ) を指定しています。
Accept-Language: en-US,en;q=0.9,es-CL;q=0.8
アプリのカルチャは、アプリのサポートされているカルチャに一致する最初に要求された言語を照合することで設定されます。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
(Startup.cs
) でアプリでサポートされているカルチャを指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CL" })
.AddSupportedUICultures(new[] { "en-US", "es-CL" }));
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、グローバリゼーションのしくみを確認します。 英語 (米国) (en-US
) で要求を発行します。 ブラウザーの言語設定で、スペイン語 (チリ) (es-CL
) に切り替えます。 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-CL
) の場合、レンダリングされるコンポーネントでは、日/月の日付書式設定 (7/6
)、24 時間制の時刻、および数値でピリオド、小数点値でコンマの区切り記号 (1.999,69
) が使用されます。
- 日付: 7/6/2021 6:49:38
- 数値: 1.999,69
カルチャを静的に設定する
既定では、Blazor WebAssembly アプリに対する中間言語 (IL) リンカーの構成によって、明示的に要求されたロケールを除き、国際化情報が削除されます。 詳しくは、「ASP.NET Core Blazor 用のリンカーを構成する」をご覧ください。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 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-CL
) に切り替えます。 Web ページを再度要求します。 要求された言語がスペイン語 (チリ) である場合、アプリのカルチャは英語 (米国) (en-US
) のままです。
ユーザー設定によってカルチャを動的に設定する
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 次の例は、ブラウザーのローカル ストレージを使用する方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
Blazor WebAssembly アプリ内のアプリのカルチャは、Blazor フレームワークの API を使用して設定されます。 ユーザーのカルチャの選択は、ブラウザーのローカル ストレージに保存できます。
wwwroot/index.html
ファイルの Blazor の <script>
タグの後、かつ </body>
終了タグの前に、JS 関数を指定して、ユーザーが選択したカルチャをブラウザーのローカル ストレージで取得および設定します。
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
System.Globalization と Microsoft.JSInterop の名前空間を Program.cs
の先頭に追加します。
using System.Globalization;
using Microsoft.JSInterop;
Program.cs
から次の行を削除します。
- await builder.Build().RunAsync();
前の行を、次のコードで置き換えます。 このコードを使用すると、Blazor のローカライズ サービスが AddLocalization を含むアプリのサービス コレクションに追加されたり、JS 相互運用が JS への呼び出しに使用されたりすることに加え、ローカル ストレージからユーザーが選択したカルチャが取得されます。 ローカル ストレージにユーザーのカルチャが含まれていない場合、コードは英語 (米国) (en-US
) の既定値を設定します。
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
重要
IStringLocalizer と IStringLocalizer<T> を使うには、常に、DefaultThreadCurrentCulture と DefaultThreadCurrentUICulture を同じカルチャに設定します。
次の CultureSelector
コンポーネントは、JS 相互運用を使用して、ユーザーが選択したカルチャをブラウザーのローカル ストレージに設定する方法を示しています。 コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JS;
js.InvokeVoid("blazorCulture.set", value.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
}
注意
IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。
Shared/MainLayout.razor
の <div class="main">
要素の </div>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
アプリがユーザーの好みを格納する可能性がある場所の例としては、ブラウザーのローカル ストレージ (Blazor WebAssembly アプリ で一般的)、ローカライズ用の cookie またはデータベース (Blazor Server アプリで一般的)、外部データベースに接続され Web API によってアクセスされる外部サービスがあります。 以下の例では、ローカライズ cookie の使用方法を示しています。
アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
Blazor Server アプリは、ローカライズ ミドルウェアを使用してローカライズされます。 AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
アプリの既定とサポートされるカルチャを RequestLocalizationOptions に設定します。
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
次の例では、ローカライズ ミドルウェアによって読み取ることができる cookie で現在のカルチャを設定する方法を示します。
次の名前空間を Pages/_Host.cshtml
ファイルの先頭に追加します。
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Pages/_Host.cshtml
の <body>
開始タグの直後に、次の Razor 式を追加します。
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Startup.Configure
のミドルウェア パイプラインでのローカライズ ミドルウェアの順序付けについては、「ASP.NET Core のミドルウェア」を参照してください。
アプリがコントローラー アクションを処理するように構成されていない場合:
Startup.ConfigureServices
でサービス コレクションに対して AddControllers を呼び出して、MVC サービスを追加します。services.AddControllers();
IEndpointRouteBuilder で MapControllers を呼び出し、
Startup.Configure
でコントローラー エンドポイント ルーティングを追加します。endpoints.MapControllers();
次の例は、行が追加された後の UseEndpoints への呼び出しを示しています。
app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
ユーザーがカルチャを選択できるように 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
コンポーネントでは、ユーザーがカルチャを選択したときに、最初のリダイレクトを実行する方法を示しています。 コンポーネントは、アプリ全体で使用するために Shared
フォルダーに配置されます。
Shared/CultureSelector.razor
:
@using System.Globalization
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="Culture">
@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-CL"),
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Shared/MainLayout.razor
の <div class="main">
要素の </div>
終了タグ内に、CultureSelector
コンポーネントを追加します。
<div class="bottom-row px-4">
<CultureSelector />
</div>
「デモンストレーション コンポーネント」セクションに示されている CultureExample1
コンポーネントを使用して、前述の例のしくみを確認します。
ローカライズ
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」セクションに従って、カルチャの選択をまだサポートしていない場合は、アプリに Microsoft.Extensions.Localization
パッケージを追加します。
Note
.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。
既定では、Blazor WebAssembly アプリに対する中間言語 (IL) リンカーの構成によって、明示的に要求されたロケールを除き、国際化情報が削除されます。 詳しくは、「ASP.NET Core Blazor 用のリンカーを構成する」をご覧ください。
Program.cs
で、System.Globalization の名前空間をファイルの先頭に追加します。
using System.Globalization;
Program.cs
の AddLocalization を使用して、アプリのサービスコレクションに Blazor のローカライズ サービスを追加します。
builder.Services.AddLocalization();
ローカライズ ミドルウェアを使用して、アプリのカルチャを設定します。
アプリで、この記事の「ユーザー設定によってカルチャを動的に設定する」に従って、カルチャの選択をまだサポートしていない場合は、次の手順を実行します。
- AddLocalization を使用して、ローカライズ サービスをアプリに追加します。
- アプリの既定とサポートされるカルチャを
Startup.Configure
(Startup.cs
) で指定します。 次の例では、英語 (米国) とスペイン語 (チリ) でサポートされるカルチャを構成しています。
Startup.ConfigureServices
(Startup.cs
):
services.AddLocalization();
ルーティング ミドルウェアが処理パイプラインに追加された直後に、Startup.Configure
で以下を行います。
var supportedCultures = new[] { "en-US", "es-CL" };
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 の使用をお勧めします。 この記事の「ユーザー設定によってカルチャを動的に設定する」セクションを参照して、ユーザーが選択したカルチャを保持する Pages/_Host.cshtml
ファイルの Razor 式の例を参照してください。
このセクションのローカライズされたリソースの例は、この記事の前の例と連動しています。アプリのサポートされているカルチャは、既定のロケールとして英語 (en
)、ユーザー選択可能またはブラウザー指定の代替ロケールとしてスペイン語 (es
) になっています。
ロケールごとにリソースを作成します。 次の例では、既定の Greeting
文字列のリソースが作成されます。
- 英語:
Hello, World!
- スペイン語 (
es
):¡Hola, Mundo!
Note
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を Hello, World!
に設定します。 ファイルを保存します。
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>
注意
次のリソース ファイルを Visual Studio に追加するには、プロジェクトの Pages
フォルダーを右クリックし、[追加]>[新しい項目]>[リソースファイル] の順に選択します。 そのファイルに CultureExample2.es.resx
という名前を付けます。 エディターが表示されたら、新しいエントリのデータを指定します。 名前を Greeting
に設定し、値を ¡Hola, Mundo!
に設定します。 ファイルを保存します。
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
Pages/CultureExample2.razor
:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
必要に応じて、CultureExample2
コンポーネントの Shared/NavMenu.razor
のナビゲーションにメニュー項目を追加します。
共有リソース
ローカライズ共有リソースを作成するには、次の方法を使用します。
任意のクラス名を持つダミーのクラスを作成します。 次に例を示します。
- アプリは
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
Note
Localization
は、LocalizationOptions を介して設定することができるリソース パスです。Razor コンポーネントの挿入された IStringLocalizer<T> のダミー クラスを参照するには、ローカライズ名前空間の
@using
ディレクティブを配置するか、ダミー クラス参照にローカライズ名前空間を含めます。 次の例で以下を実行します。- 最初の例では、
@using
ディレクティブを使用してSharedResource
ダミー クラスのLocalization
名前空間を指定します。 - 2 番目の例では、
SharedResource
ダミー クラスの名前空間を明示的に指定します。
Razor コンポーネントでは、次の "いずれか" の方法を使用します。
@using Localization @inject IStringLocalizer<SharedResource> Loc
@inject IStringLocalizer<Localization.SharedResource> Loc
- 最初の例では、
その他のガイダンスについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」を参照してください。