events
ASP.NET Core アプリのコンテンツをローカライズ可能にする
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
作成者: Hisham Bin Ateya、Damien Bowden、Bart Calixto、Nadeem Afana
アプリをローカライズするためのタスクの 1 つは、ローカライズ可能なコンテンツを、異なるカルチャ用にそのコンテンツを置き換えやすくするコードでラップすることです。
IStringLocalizer と IStringLocalizer<T> は、ローカライズされたアプリの開発時に生産性が向上するように設計されています。 IStringLocalizer
では、ResourceManager と ResourceReader を使用して、実行時にカルチャ固有のリソースを提供します。 インターフェイスには、ローカライズされた文字列を返すためのインデクサーと IEnumerable
があります。 IStringLocalizer
では、既定の言語文字列をリソース ファイルに格納する必要はありません。 ローカリゼーションの対象となるアプリを開発することができ、開発の早い段階でリソース ファイルを作成する必要はありません。
次のコード例は、ローカライズのために文字列 "About Title" をラップする方法を示しています。
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers;
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
前のコードの IStringLocalizer<T>
の実装は、依存関係の挿入で説明したものです。 "About Title" のローカライズされた値が見つからない場合、インデクサーのキー、つまり文字列 "About Title" が返されます。
アプリで、既定の言語のリテラル文字列をそのままにし、ローカライザーにそれらをラップすることができるので、アプリの開発に専念することができます。 既定の言語でアプリを開発し、既定のリソース ファイルを最初に作成せずに、ローカライズ手順に向けて準備します。
または、従来のアプローチを使用し、既定の言語文字列を取得するキーを提供できます。 多くの開発者にとって、既定の言語の .resx ファイルを使用せずに、文字列リテラルをラップするだけの新しいワークフローは、アプリをローカライズする際のオーバーヘッドの削減になります。 従来のワークフローを好む開発者もいます。長い文字列リテラルの操作が容易で、ローカライズされた文字列を更新しやすいためです。
HTML を格納しているリソースには、IHtmlLocalizer<TResource> の実装を使用します。 IHtmlLocalizer は、リソース文字列で書式設定される引数を HTML エンコードしますが、リソース文字列自体は HTML エンコードしません。 次の強調表示されたコードでは、name
パラメーターの値のみが HTML エンコードされます。
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers;
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
注: 一般に、HTML ではなく、テキストのみをローカライズします。
最下位のレベルでは、IStringLocalizerFactory は依存関係の挿入から取得できます。
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
return View();
}
上記のコードは、2 つの各ファクトリ作成メソッドを示しています。
ローカライズされた文字列は、コントローラーまたは領域で仕切るか、1 つのコンテナーにすることができます。 サンプル アプリでは、共有されるリソースのために SharedResource
というマーカー クラスを使用しています。 マーカー クラスは呼び出されることはありません。
// Dummy class to group shared resources
namespace Localization;
public class SharedResource
{
}
次のサンプルでは、InfoController
と SharedResource
のローカライザーが使用されています。
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
IViewLocalizer サービスは、ビューのローカライズされた文字列を提供します。 ViewLocalizer
クラスは、このインターフェイスを実装し、ビューのファイル パスからリソースの場所を見つけます。 次のコードは、IViewLocalizer
の既定の実装の使用方法を示しています。
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
IViewLocalizer
の既定の実装は、ビューのファイル名に基づいてリソース ファイルを見つけます。 グローバルな共有リソース ファイルを使用するオプションはありません。 ViewLocalizer
は、IHtmlLocalizer
を使用してローカライザーを実装するので、Razor は、ローカライズされた文字列を HTML エンコードしません。 リソース文字列をパラメーター化することができます。IViewLocalizer
は、パラメーターを HTML エンコードしますが、リソース文字列は HTML エンコードしません。 次の Razor マークアップがあるとします。
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
フランス語のリソース ファイルには、次の値を含めることができます。
キー | [値] |
---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
描画されたビューには、リソース ファイルからの HTML マークアップが含まれます。
一般に、HTML ではなく、"テキストのみをローカライズ" します。
ビュー内の共有リソース ファイルを使用するには、IHtmlLocalizer<T>
を挿入します。
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
DataAnnotations エラー メッセージは IStringLocalizer<T>
を使用してローカライズします。 オプション ResourcesPath = "Resources"
を使用して、RegisterViewModel
のエラー メッセージを次のいずれかのパスに格納できます。
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
using System.ComponentModel.DataAnnotations;
namespace Localization.ViewModels.Account;
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.",
MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage =
"The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
非検証属性はローカライズされます。
次のコードは、複数のクラスに検証属性の 1 つのリソース文字列を使用する方法を示しています。
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
上記のコードでは、SharedResource
は、.resx ファイルに対応するクラスであり、ここに検証メッセージが格納されます。 この方法では、DataAnnotations は、各クラスのリソースではなく、SharedResource
のみを使用します。
ローカライズ サービスは、Program.cs
で構成されます。
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization により、サービス コンテナーにローカライズ サービスが追加されます (
IStringLocalizer<T>
とIStringLocalizerFactory
の実装を含む)。 また、上記のコードでは、リソース パスが "Resources" に設定されます。AddViewLocalization は、ローカライズされたビュー ファイルのサポートを追加します。 このサンプルでは、ビューのローカライズはビュー ファイルのサフィックスに基づいています。 たとえば、
Index.fr.cshtml
ファイルの "fr" です。AddDataAnnotationsLocalization は、
IStringLocalizer
抽象化を介してローカライズされたDataAnnotations
検証メッセージのサポートを追加します。
注意
小数フィールドに小数点のコンマを入力できない場合があります。 小数点にコンマ (",") を使い、英語 (米国) 以外の日付形式を使う英語以外のロケールの jQuery 検証をサポートするには、アプリをグローバル化する手順を行う必要があります。 小数点のコンマを追加する手順については、こちらの GitHub コメント 4076 を参照してください。
アプリのローカライズには、次のタスクも含まれます。
- ASP.NET Core でミドルウェアをフィルターとして使用する URL カルチャ プロバイダー
- ミドルウェアをフィルターとして使用して RouteDataRequest CultureProvider をグローバルに適用する
- ASP.NET Core のグローバリゼーションおよびローカリゼーション
- ASP.NET Core アプリで言語とカルチャ用にローカライズされたリソースを提供する
- ローカライズされた ASP.NET Core アプリで言語とカルチャを選択するための戦略
- ASP.NET Core のローカライズに関するトラブルシューティング
- .NET アプリケーションのグローバライズとローカライズ
- 記事で使用されている Localization.StarterWeb プロジェクト。
- .resx ファイル内のリソース
- Microsoft 多言語アプリ ツールキット
- ローカリゼーションとジェネリック
作成者: Rick Anderson、Damien Bowden、Bart Calixto、Nadeem Afana、Hisham Bin Ateya
アプリをローカライズするためのタスクの 1 つは、ローカライズ可能なコンテンツを、異なるカルチャ用にそのコンテンツを置き換えやすくするコードでラップすることです。
IStringLocalizer と IStringLocalizer<T> は、ローカライズされたアプリの開発時に生産性が向上するように設計されています。 IStringLocalizer
では、ResourceManager と ResourceReader を使用して、実行時にカルチャ固有のリソースを提供します。 インターフェイスには、ローカライズされた文字列を返すためのインデクサーと IEnumerable
があります。 IStringLocalizer
では、既定の言語文字列をリソース ファイルに格納する必要はありません。 ローカリゼーションの対象となるアプリを開発することができ、開発の早い段階でリソース ファイルを作成する必要はありません。
次のコード例は、ローカライズのために文字列 "About Title" をラップする方法を示しています。
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
}
前のコードの IStringLocalizer<T>
の実装は、依存関係の挿入で説明したものです。 "About Title" のローカライズされた値が見つからない場合、インデクサーのキー、つまり文字列 "About Title" が返されます。
アプリで、既定の言語のリテラル文字列をそのままにし、ローカライザーにそれらをラップすることができるので、アプリの開発に専念することができます。 既定の言語でアプリを開発し、既定のリソース ファイルを最初に作成せずに、ローカライズ手順に向けて準備します。
または、従来のアプローチを使用し、既定の言語文字列を取得するキーを提供できます。 多くの開発者にとって、既定の言語の .resx ファイルを使用せずに、文字列リテラルをラップするだけの新しいワークフローは、アプリをローカライズする際のオーバーヘッドの削減になります。 従来のワークフローを好む開発者もいます。長い文字列リテラルの操作が容易で、ローカライズされた文字列を更新しやすいためです。
HTML を格納しているリソースには、IHtmlLocalizer<T>
の実装を使用します。 IHtmlLocalizer
は、リソース文字列で書式設定される引数を HTML エンコードしますが、リソース文字列自体は HTML エンコードしません。 次の強調表示されたコードでは、name
パラメーターの値のみが HTML エンコードされます。
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers
{
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
注意
一般に、HTML ではなく、テキストのみをローカライズします。
最下位のレベルでは、依存関係の挿入から IStringLocalizerFactory
を取得できます。
{
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
上記のコードは、2 つの各ファクトリ作成メソッドを示しています。
ローカライズされた文字列は、コントローラーまたは領域で仕切るか、1 つのコンテナーにすることができます。 サンプル アプリでは、共有されるリソースのために SharedResource
というダミー クラスを使用しています。
// Dummy class to group shared resources
namespace Localization
{
public class SharedResource
{
}
}
一部の開発者は、Startup
クラスを使用してグローバル文字列または共有文字列を格納します。 次のサンプルでは、InfoController
と SharedResource
のローカライザーが使用されています。
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
IViewLocalizer
サービスは、ビューのローカライズされた文字列を提供します。 ViewLocalizer
クラスは、このインターフェイスを実装し、ビューのファイル パスからリソースの場所を見つけます。 次のコードは、IViewLocalizer
の既定の実装の使用方法を示しています。
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
IViewLocalizer
の既定の実装は、ビューのファイル名に基づいてリソース ファイルを見つけます。 グローバルな共有リソース ファイルを使用するオプションはありません。 ViewLocalizer
は、IHtmlLocalizer
を使用してローカライザーを実装するので、Razor は、ローカライズされた文字列を HTML エンコードしません。 リソース文字列をパラメーター化することができます。IViewLocalizer
は、パラメーターを HTML エンコードしますが、リソース文字列は HTML エンコードしません。 次の Razor マークアップがあるとします。
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
フランス語のリソース ファイルには、次の値を含めることができます。
キー | [値] |
---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
描画されたビューには、リソース ファイルからの HTML マークアップが含まれます。
注意
一般に、HTML ではなく、テキストのみをローカライズします。
ビュー内の共有リソース ファイルを使用するには、IHtmlLocalizer<T>
を挿入します。
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
DataAnnotations エラー メッセージは IStringLocalizer<T>
を使用してローカライズします。 オプション ResourcesPath = "Resources"
を使用して、RegisterViewModel
のエラー メッセージを次のいずれかのパスに格納できます。
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
ASP.NET Core MVC 1.1.0 以降では、非検証属性がローカライズされます。
次のコードは、複数のクラスに検証属性の 1 つのリソース文字列を使用する方法を示しています。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
上記のコードでは、SharedResource
は、.resx ファイルに対応するクラスであり、ここに検証メッセージが格納されます。 この方法では、DataAnnotations は、各クラスのリソースではなく、SharedResource
のみを使用します。
ローカライズ サービスは、Startup.ConfigureServices
メソッドで構成されます。
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization
により、サービス コンテナーにローカライズ サービスが追加されます (IStringLocalizer<T>
とIStringLocalizerFactory
の実装を含む)。 また、上記のコードでは、リソース パスが "Resources" に設定されます。AddViewLocalization
は、ローカライズされたビュー ファイルのサポートを追加します。 このサンプルでは、ビューのローカライズはビュー ファイルのサフィックスに基づいています。 たとえば、Index.fr.cshtml
ファイルの "fr" です。AddDataAnnotationsLocalization
は、IStringLocalizer
抽象化を介してローカライズされたDataAnnotations
検証メッセージのサポートを追加します。
注意
小数フィールドに小数点のコンマを入力できない場合があります。 小数点にコンマ (",") を使い、英語 (米国) 以外の日付形式を使う英語以外のロケールの jQuery 検証をサポートするには、アプリをグローバル化する手順を行う必要があります。 小数点のコンマを追加する手順については、こちらの GitHub コメント 4076 を参照してください。
アプリのローカライズには、次のタスクも含まれます。
ASP.NET Core に関するフィードバック
ASP.NET Core はオープンソース プロジェクトです。 フィードバックを提供するにはリンクを選択します。
その他のリソース
トレーニング
モジュール
共有リソースを使用して一貫性のある .NET MAUI XAML ページを設計する - Training
静的共有リソースと動的共有リソースを使用して .NET Multi-Platform App UI (MAUI) ユーザー インターフェイスを構築する方法について説明します。 また、スタイルを使用することで、ユーザー インターフェイスが一貫性とアクセス性の両方を備えたものになることを確認します。
ドキュメント
-
ASP.NET Core のローカライズに関するトラブルシューティング
ASP.NET Core アプリのローカライズに関する問題を診断する方法について説明します。
-
ローカライズされた ASP.NET Core アプリで言語とカルチャを選択するための戦略
ASP.NET Core アプリでコンテンツをさまざまな言語とカルチャにローカライズする場合に、言語とカルチャを選択する方法について説明します。
-
ASP.NET Core のグローバリゼーションおよびローカリゼーション
ASP.NET Core がコンテンツをさまざまな言語と文化にローカライズするために提供するサービスとミドルウェアについて説明します。