へっぽこプログラマーの備忘録
プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。
menu
keyboard_arrow_up
Top
search
close
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
Home
›
C#
›
ASP.NET Core における多言語対応
2017/09/15
ASP.NET Core における多言語対応
update
event_note
label
ASP.NET Core
label
C#
ASP.NET Core において、多言語に対応したサイトを構築すればどうすればいいかについて調べてみました。 基本的には Microsoft のサイトで解説されている通りです。
ちなみに、MSDN では言語コードと国コードの組み合わせのことをカルチャーと表記していたので、ここでもカルチャーという言葉を使用したいと思います。 ## 環境 - Visual Studio 2017 - ASP.NET Core 2.0 以下、ASP.NET Core 2.0 のテンプレートプロジェクトをベースに説明しています。 ## 準備 ASP.NET Core でローカライズを行う場合、DI により `IStringLocalizer
` や `IHtmlLocalizer
` を注入するようです。 まずは `Startup.cs` の `ConfigureServices` メソッドで、以下のように `AddLocalization` `AddViewLocalization` `AddDataAnnotationsLocalization` を追加します。 ```csharp public void ConfigureServices(IServiceCollection services) { services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddMvc() .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; }) .AddDataAnnotationsLocalization(); } ``` `ResourcesPath` でリソースファイルのある場所を指定しています。 ここではプロジェクトの配下に `Resources` というフォルダを作成して、そこに後述するリソースファイルを配置するようにしています。 `LanguageViewLocationExpanderFormat.Suffix` はビューファイル(`cshtml` ファイル)をカルチャー毎に分ける場合に、そのファイル名をサフィックスに基づいて解決することを指定しています(後述)。 `AddDataAnnotationsLocalization` は DataAnnotations のローカライズを行うために必要なので、今回の内容の範囲外となります。 ### リクエストに対するカルチャーの選択 HTTP リクエストに対するカルチャーの設定はミドルウェアで処理されます。 具体的には `Startup.cs` の `Configure` メソッドで以下のようにして有効化します。 ```cs using System.Globalization; using Microsoft.AspNetCore.Localization; public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 中略 var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("en-AU"), new CultureInfo("en-GB"), new CultureInfo("en"), new CultureInfo("es-ES"), new CultureInfo("es-MX"), new CultureInfo("es"), new CultureInfo("fr-FR"), new CultureInfo("fr"), }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("en-US"), // Formatting numbers, dates, etc. SupportedCultures = supportedCultures, // UI strings that we have localized. SupportedUICultures = supportedCultures }); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } ``` リクエストからカルチャーを決定できない場合には、`DefaultRequestCulture` で指定されたカルチャーが使用されます。 (上記では、未対応のカルチャーに対しては英語が表示されます。) 一応注意として、`app.UseMvcWithDefaultRoute()` などは内部でリクエストのカルチャーをチェックする可能性があるらしいので、その前に構成する必要があるようです。 ## リソースファイルの作り方と命名規則 実際に表示される文字は、リソースファイルを作成してそこに記入していきます。 リソースファイルは以下のようにして追加します。 1. プロジェクトを右クリックし、[追加] > [新しい項目] を選択します。 1. [リソースファイル]を選択して作成します。 リソースファイルを作成するとデザイナーが表示され、名前と値の組み合わせが記入できるようになっていると思います。 ※詳しい手順は[Microsoft](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/localization) のサイトに画像付きで載っています。 `名前` にキーを入力し、`値` にローカライズした場合の文字列を書きます。 尚、リソースファイル名は以下のようなネーミングルールとなっており、フォルダの階層で分ける方法と、ファイル名をドットで区切る方法があるみたいです。 **Controller の場合** - `Resources/Controllers/HomeController.ja.resx` - `Resources/Controllers.HomeController.ja.resx` **View の場合** - `Resources/Views/Home/About.ja.resx` - `Resources/Views.Home.About.ja.resx` また、View の場合は `cshtml` ファイル自体をカルチャー毎に分けることもできます。 この場合、リソースファイルと同じように、ファイル名を `index.ja.cshtml` にして作成するようですが、ここでは扱いません。 上記では日本語の例として `ja` を指定していますが、カルチャー名は省略することもでき、カルチャー名のないリソースファイルはデフォルトのリソースファイル(未対応のカルチャーが指定された場合に使用されるリソースファイル)として扱われます。 尚、Visual Studio でカルチャー名を省略してリソースファイルを作成すると、各文字列のプロパティを持つ C# クラス (`.Designer.cs`) が自動で作成されますが、ASP.NET Core ではこれは不要なようです。 また、Microsoft のページではデフォルトのリソースファイル(カルチャー名のないリソースファイル)は多くの場合必要ないと書かれていますが、個人的には英語はカルチャー名のないリソースファイルで作成するのがよいのではないかと思っています。 理由は、長文の場合にキーに直接記述すると大変なので、抽象化した文字列をキーとして使用したほうが良いのではないかと考えているからです。 実際、GitHub でいろいろな人のリソースファイルの書き方を調べてみると、そのように書いている人が多い印象でした。 ## 使用方法 ### Controller の場合 DI で `IStringLocalizer` を受けます。 例えば `HomeController` の場合は以下のようにです。 ```cs private readonly IStringLocalizer
localizer; public HomeController(IStringLocalizer
localizer) { this.localizer = localizer; } ``` この `localizer` を使って例えば以下のように書きます。 ```cs public IActionResult About() { //ViewData["Message"] = "Your application description page."; ViewData["Message"] = localizer["hoge"]; return View(); } ``` ここで `hoge` という文字列がローカライズされていれば、ローカライズされた文字列が表示されます。 ### View の場合 以下のように記述することでローカライズできます。 ```csharp @using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["hoge"]; } ``` ### ローカライズされていない場合の挙動 ローカライズされていない場合、以下のように動作しました。 - デフォルトのリソースファイル(カルチャー名のないリソースファイル)があれば、そのリソースファイルで定義された値が表示される - デフォルトのリソースファイルがない、またはデフォルトのリソースファイルでも名前(キー)が定義されていない場合、`hoge` という値がそのまま表示されるようです。 デフォルトのリソースファイル(カルチャー名のないリソースファイル)は必須ではありませんが、上記のような動作と前述した理由により個人的には作成したほうが良いと思っています。 ## カルチャーの指定方法 基本的にはブラウザの設定によって適切なカルチャーが設定されて画面が表示されます。 ユーザー側が任意のカルチャーを指定するには、いくつか方法があるようです。 #### QueryStringRequestCultureProvider URLにクエリ文字列を追加して指定する方法で、コードのデバッグやテストに役立ちます。 - `http://localhost:5000/?culture=ja-JP&ui-culture=ja-JP` `culture` は Controller、`ui-culture` は View 用の指定です。 `culture=ja-JP` とだけ指定すると、`ui-culture` でも同じ値が使用されます。 #### CookieRequestCultureProvider ※追々書くかも #### The Accept-Language HTTP header ※追々書くかも ## 言語が切り替わらないときは? ここが一番はまりました・・・。 リソースファイルもプログラムも正しいのに言語が切り替わらない。 しかも `Debug` モードだけ。 `Release` モードでは上手く切り替わる。 原因不明ですが、`bin` フォルダの中の `Debug` フォルダを一度削除したら正しく切り替わるようになりました。 ## 参考 URL - https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/localization - http://tech.tanaka733.net/entry/resource-file-naming-in-aspnetcore-localization - http://blog.livedoor.jp/monthly_check/archives/70915210.html - https://andrewlock.net/adding-localisation-to-an-asp-net-core-application/ - https://www.tmp1024.com/programming/asp-net-core-internationalization-files - https://joonasw.net/view/aspnet-core-localization-deep-dive - http://grabacr.net/archives/1647
tweet
facebook
Pocket
B!
はてブ
LINE
chevron_left
chevron_right
Translate
Popular Posts
Docker for Windows の設定
TortoiseGit でコミットメッセージを変更する
image
NO IMAGE
smbclient で session setup failed: NT_STATUS_LOGON_FAILURE が表示される
TortoiseGit でブランチ間の差分を見る
image
NO IMAGE
マージ元ブランチとマージ先ブランチ
[Python] 文字列の判定で、None と空文字を同時に判定する
[Python] Tesseract で OCR を行ったら `UnicodeEncodeError: 'ascii' codec can't encode characters` のエラーが表示された
image
NO IMAGE
GitLab Runner でクローンする URL を変更する
[Python] matplotlib で plot する際に "Tcl_AsyncDelete: async handler deleted by the wrong thread" というエラーがでる
image
NO IMAGE
[JavaScript] コンストラクタで await したい
Labels
.NET Core
31
.NET Framework
17
.NET Standard
2
AdminLTE
1
AI
1
Apache
3
AppVeyor
2
AsciiDoc
3
ASP.NET Core
55
Atom
4
AWS
5
AWS Cloud9
4
blockdiag
1
Blogger
13
Bootstrap
3
C/C++
6
C#
106
CentOS
3
Chrome
1
Chronograf
3
chrony
1
Codecov
1
CSS
1
Docker
79
DokuWiki
4
Doxygen
1
draw.io
1
EasyTag
1
Electron
1
Electron.NET
2
Entity Framework Core
9
Excel
2
FFmpeg
3
Firefox
6
Flask
1
Git
19
GitBook
4
GitBucket
7
GitHub
7
GitLab
39
Go
1
Google
1
Google Cloud Platform
1
Grafana
13
GStreamer
2
HTML
5
IIS
8
InfluxDB
14
JavaScript
15
Jenkins
7
Linux
33
Log4View
1
MahApps.Metro
3
MaterialDesignInXamlToolkit
1
MkDocs
2
MongoDB
5
MVC
1
MVVM
6
nginx
3
NLog
3
Node.js
8
npm
1
NVIDIA
3
onvif
1
OpenAPI
2
OpenCV
4
OpenSSL
3
OpenVINO
2
ownCloud
2
pandas
1
Pine Script
1
PlantUML
5
Portainer
3
PowerShell
8
Prism
2
PySide
17
Python
85
PyTorch
1
RabbitVCS
1
Razor
3
Redmine
33
Redoc
1
remark.js
2
rocketchat
10
Ruby
3
scikit-learn
1
SignalR
1
Slack
1
Socket.IO
1
SonarQube
5
Sphinx
10
SQL Server
5
SQLite
1
StableDiffusion
1
Subversion
2
Swagger
1
Swarmpit
1
Syslog
3
Telegraf
6
Tesseract
3
TestLink
2
Tomcat
2
TortoiseGit
11
TortoiseSVN
2
Trading View
1
Traefik
3
Travis CI
1
Ubuntu
31
Visual Studio
39
Visual Studio Code
10
VSCode
8
Vue.js
8
Windows
62
Windows 10
5
Windows ADK
1
Windows API
2
Windows Embedded
4
wkhtmltopdf
2
Word
3
WPF
12
WSL
5
WSL2
5
Xamarin
1
xUnit
5
yaml
1
yolo
1
アプリケーション
1
デザインパターン
1
テスト
1
バッチファイル
2
プログラミング
4
ライセンス
1
暗号資産(仮想通貨)
1
英語
2
確定申告
1
機械学習
1
強化学習
1
雑記
1
書籍
1
数学
1
正規表現
1
Blog Archive
►
2024
(7)
►
3月
(1)
►
2月
(5)
►
1月
(1)
►
2023
(30)
►
12月
(3)
►
11月
(5)
►
10月
(2)
►
9月
(1)
►
8月
(2)
►
7月
(4)
►
6月
(2)
►
5月
(3)
►
4月
(2)
►
3月
(2)
►
2月
(3)
►
1月
(1)
►
2022
(106)
►
12月
(5)
►
11月
(1)
►
10月
(3)
►
9月
(6)
►
8月
(7)
►
7月
(6)
►
6月
(13)
►
5月
(9)
►
4月
(15)
►
3月
(11)
►
2月
(14)
►
1月
(16)
►
2021
(85)
►
12月
(11)
►
11月
(6)
►
10月
(4)
►
9月
(10)
►
8月
(8)
►
7月
(4)
►
6月
(18)
►
5月
(7)
►
4月
(8)
►
3月
(2)
►
2月
(2)
►
1月
(5)
►
2020
(56)
►
12月
(1)
►
11月
(3)
►
10月
(3)
►
9月
(3)
►
8月
(3)
►
7月
(7)
►
6月
(7)
►
5月
(2)
►
4月
(6)
►
3月
(6)
►
2月
(3)
►
1月
(12)
►
2019
(92)
►
12月
(13)
►
11月
(9)
►
10月
(3)
►
9月
(2)
►
8月
(3)
►
7月
(5)
►
6月
(11)
►
5月
(6)
►
4月
(17)
►
3月
(9)
►
2月
(6)
►
1月
(8)
►
2018
(100)
►
12月
(1)
►
11月
(11)
►
10月
(8)
►
9月
(6)
►
8月
(10)
►
7月
(10)
►
6月
(8)
►
5月
(9)
►
4月
(8)
►
3月
(14)
►
2月
(4)
►
1月
(11)
▼
2017
(117)
►
12月
(14)
►
11月
(20)
►
10月
(17)
▼
9月
(19)
GitLab Runner を docker-compose で動かす
PlantUML サーバーを docker-compose で動かす
Windows 10 の便利なショートカットキー
ASP.NET Core Identity を使わない認証
Docker for Windows のインストール
Surface Pro (2017) の Mini DisplayPort から音が出なくなった
.NET Core コンソールアプリケーションにおけるロギングや設定について
Blogger API を使用するための準備
Vaster2 の適用とカスタマイズ
ASP.NET Core における多言語対応
Log4View で NLog のログを閲覧する
Doxygen を使ってソースコードからドキュメントを作成する
.NET Core SDK 2.0 のインストール
SQL Server 2016 Express の暗号化
SQL Server にテーブルを作成する
SQL Server にデータベースを新規作成する
SQL Server 2016 Express のインストール
プログラミング・IT技術関連書フェアが Amazon で開催中
Visual Studio と Visual Studio Installer が起動しなくなった
►
8月
(10)
►
7月
(8)
►
6月
(3)
►
5月
(6)
►
4月
(5)
►
3月
(2)
►
2月
(8)
►
1月
(5)
►
2016
(91)
►
12月
(5)
►
11月
(9)
►
10月
(11)
►
9月
(9)
►
8月
(6)
►
7月
(14)
►
6月
(14)
►
5月
(11)
►
4月
(10)
►
3月
(2)
►
2015
(23)
►
12月
(4)
►
11月
(2)
►
10月
(8)
►
9月
(8)
►
7月
(1)
►
2013
(3)
►
11月
(1)
►
9月
(1)
►
7月
(1)
►
2012
(2)
►
7月
(1)
►
6月
(1)
►
2011
(1)
►
9月
(1)
►
2009
(1)
►
7月
(1)
►
2008
(2)
►
11月
(1)
►
7月
(1)
►
2007
(3)
►
10月
(3)