ASP.NET Coreのローカライズする際のリソースファイル名についてこのドキュメントを読んで気になったことがあったのでまとめました。
Globalization and localization | Microsoft Docs
ローカライズそのものについてはこのドキュメントを参考にしてください。また、ローカライズに必要なNuGetパッケージですが、MVCの機能を使うためにMicrosoft.AspNetCore.Mvc
を追加している場合は、依存しているMicrosoft.AspNetCore.Mvc.Localization
とさらにこれが依存しているMicrosoft.AspNetCore.Localization
がインストールされるので特に追加は不要です。MVCを使わずにローカライズしたい場合はMicrosoft.AspNetCore.Localization
が必要です。
はじめに
ASP.NET Coreでローカライズする場合、IStringLocalizer<T>
やIHtmlLocalizer<T>
を指定してDIでローカライザーを注入します。この時、クラスTごろにリソースファイルを準備します。Viewの場合はIViewLocalizer
、ViewModelの場合は特に指定は不要ですが、クラスごとにリソースファイルを準備するのは同じです。さて、このクラスTごとにリソースファイルを準備する際に、ファイル名が規約で決まっており規約に従っていないと正しく読み込めません。ここで少しはまったので説明します。
起点フォルダ
まず、リソースファイル名を置く起点となるフォルダですが、これはStartup.cs
でResourcesPath
に指定したフォルダ名になります。これは空白でも可能でその場合はプロジェクトのルートフォルダと同一になります。以下の説明では下記のコードの通り "Resources" を指定しているものとします。
public void ConfigureServices(IServiceCollection services) { //省略 services.AddLocalization(options => { options.ResourcesPath = "Resources"; }); //省略 }
ファイル名とアセンブリ名とクラス名と
そしてここを起点としたリソースファイルのファイルパスですが、これがリソースを指定するクラスTのクラス名が、アセンブリ名で始まっているか否かで分かれます。
どういうことかといいますと、例えばdotnet new -t web
でASP.Core MVCプロジェクトを作成するとまずアセンブリ名はプロジェクトを作成したフォルダ名と一致します。これはproject.jsonにnameプロパティが指定されていないため、フォルダ名が利用されるためです*1。
しかし、デフォルトの名前空間はWebApplication
で固定であるため、クラス名がアセンブル名で始まらないケースになってしまいます。一方、Visual StudioでASP.NET Coreプロジェクトを作成するとデフォルトではプロジェクト名がアセンブル名かつデフォルトの名前空間になるので、デフォルトの名前空間以外の名前空間にわざわざクラスを作らない限りは同じになります。
クラスTのFQDNがアセンブル名で始まる場合
例として、アセンブリ名がAspNetCore.StarterWeb
だとして、リソースを作りたいクラスがAspNetCore.StarterWeb.Controllers.HomeController
でjaロケールのリソースを作りたいとしましょう。この場合リソースファイルはプロジェクトのルートから見て、Resources\Controllers\Homecontroller.ja.resx
もしくはResources\Controllers.Homecontroller.ja.resx
となります。Resources以下を.
区切りにしてフラットに配置するか\
でフォルダ階層を切って配置するかはどちらでもよく、1つのプロジェクトで混在させることも可能です。つまり、クラスTのFQDNからアセンブリ名を省略した名前となります。これは省略できるではなく省略しないといけません。
クラスTのFQDNがアセンブル名で始まらない場合
例として、アセンブリ名がAspNetCore.StarterWeb
だとして、リソースを作りたいクラスがWebApplication.Controllers.HomeController
でjaロケールのリソースを作りたいとします。この場合はFQDNを省略できなく、Resources\WebApplication\Controllers\Homecontroller.ja.resx
もしくはResources\WebApplication.Controllers.Homecontroller.ja.resx
となります。
まとめ
- .NET Coreのアセンブリ名はproject.jsonのnameプロパティの値が使われる。指定していない場合はプロジェクトのルートフォルダのフォルダ名。
- ASP.NET Coreのリソースファイルの名前は、クラスのFQDNがアセンブリ名で始まっている場合はアセンブリ名を省略する
- そうでない場合は省略しない
ドキュメントがちょっとわかりにくいなあということでissueを投げているので、そのうち改善すると思われます。
*1:そのためフォルダ名に空白が入っていたりするとデバッグ実行のパス指定がデフォルトでは動かなくなったりと何かと面倒