ASP.NET Core アプリのコンテンツをローカライズ可能にする
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
作成者: Hisham Bin Ateya、Damien Bowden、Bart Calixto、Nadeem Afana
アプリをローカライズするためのタスクの 1 つは、ローカライズ可能なコンテンツを、異なるカルチャ用にそのコンテンツを置き換えやすくするコードでラップすることです。
IStringLocalizer
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 ファイルを使用せずに、文字列リテラルをラップするだけの新しいワークフローは、アプリをローカライズする際のオーバーヘッドの削減になります。 従来のワークフローを好む開発者もいます。長い文字列リテラルの操作が容易で、ローカライズされた文字列を更新しやすいためです。
IHtmlLocalizer
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
最下位のレベルでは、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 のローカリゼーション
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 つのリソース文字列を使う方法
次のコードは、複数のクラスに検証属性の 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
検証メッセージのサポートを追加します。
Note
小数フィールドに小数点のコンマを入力できない場合があります。 小数点にコンマ (",") を使い、英語 (米国) 以外の日付形式を使う英語以外のロケールの 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 と 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 ファイルを使用せずに、文字列リテラルをラップするだけの新しいワークフローは、アプリをローカライズする際のオーバーヘッドの削減になります。 従来のワークフローを好む開発者もいます。長い文字列リテラルの操作が容易で、ローカライズされた文字列を更新しやすいためです。
IHtmlLocalizer
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();
}
Note
一般に、HTML ではなく、テキストのみをローカライズします。
IStringLocalizerFactory
最下位のレベルでは、依存関係の挿入から 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 マークアップが含まれます。
Note
一般に、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 のローカリゼーション
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 つのリソース文字列を使う方法
次のコードは、複数のクラスに検証属性の 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
検証メッセージのサポートを追加します。
Note
小数フィールドに小数点のコンマを入力できない場合があります。 小数点にコンマ (",") を使い、英語 (米国) 以外の日付形式を使う英語以外のロケールの jQuery 検証をサポートするには、アプリをグローバル化する手順を行う必要があります。 小数点のコンマを追加する手順については、こちらの GitHub コメント 4076 を参照してください。
次のステップ
アプリのローカライズには、次のタスクも含まれます。
その他のリソース
ASP.NET Core