by WebSurfer
27. January 2023 12:35
先の記事「整数型プロパティの検証、エラーメッセージ (CORE)」の一番下に Model Binding Error Messages をローカライズする方法別途検証してみますと書きました。ローカライズと言うよりは、単に英語のエラーメッセージを日本語に差し替えるだけですが、やってみましたので以下にその方法を述べます。

.NET Framework の MVC5 アプリの場合は、先の記事「MVC5 でエラーメッセージが英語」に書いたように、NuGet から日本語のサテライトアセンブリ System.Web.Mvc.resources.dll をインストールするという手段がありますが、ASP.NET Core MVC ではそのような解決策は見つかりません。
自力でコードを書いてローカライズする方法は Stackoverflow の記事 ASP.NET Core Model Binding Error Messages Localization 他に見つかりましたのでそれを参考にしました。
だた、見つけた記事に書いてある方法は、多言語対応のため複数のリソースファイルを作り、それからカルチャに応じてその言語のエラーメッセージの文字列をリソースファイルから取得して、デフォルトのエラーメッセージを書き換えるという少々複雑なことを行っています。
先の記事のエラーメッセージ「The value '2000x' is not valid for 価格2 (int).」と「The value '' is invalid.」を日本語化するだけならコードはかなり簡単になります。リソースファイルを作ってそこからメッセージを取得するということは必要ありません。
それにはどうすればよいかと言うと、Program.cs (.NET 5.0 以前は Startup.cs) の AddControllersWithViews メソッドで DefaultModelBindingMessageProvider を取得し、SetAttemptedValueIsInvalidAccessor, SetValueMustNotBeNullAccessor メソッドを使ってデフォルトのエラーメッセージを差し替えてやります。
具体例は下のコードを見てください。Visual Studio 2022 のテンプレートで作った .NET 7.0 の ASP.NET Core MVC の場合のサンプルです。
builder.Services.AddControllersWithViews(options => {
DefaultModelBindingMessageProvider provider =
options.ModelBindingMessageProvider;
provider.SetAttemptedValueIsInvalidAccessor(
(s1, s2) => $"値 '{s1}' は {s2} に対して無効です。");
provider.SetValueMustNotBeNullAccessor(
(s) => $"値 '{s}' は無効です。");
});
上のコードにより、先の記事のデフォルトの英語のエラーメッセージ「The value '2000x' is not valid for 価格2 (int).」と「The value '' is invalid.」がそれぞれ「値 '2000x' は 価格2 (int) に対して無効です。」と「値 '' は無効です。」に書き換えられます。この記事の上の画像がその結果です。
デフォルトの Model Binding Error Messages には、上の AttemptedValueIsInvalid, ValueMustNotBeNull を含めて全部で 11 種類あります。
以下に一覧表を載せておきます。それぞれに SetXxxxxAccessor (Xxxxx は名前) というメソッドが用意されていて、それによりデフォルトのエラーメッセージを差し替えることができます。
名前 |
デフォルト |
原因 |
AttemptedValueIsInvalid |
The value '{0}' is not valid for {1}. |
Exception is of type FormatException or OverflowException, value is known, and error is associated with a property. |
ValueMustNotBeNull |
The value '{0}' is invalid. |
a null value is bound to a non-Nullable property. |
MissingBindRequiredValue |
A value for the '{0}' parameter or property was not provided. |
a property with an associated BindRequiredAttribute is not bound. |
MissingKeyOrValue |
A value is required. |
either the key or the value of a KeyValuePair<Key,TValue> is bound but not both. |
MissingRequestBodyRequiredValue |
A non-empty request body is required. |
no value is provided for the request body, but a value is required. |
NonPropertyAttemptedValueIsInvalid |
The value '{0}' is not valid. |
Exception is of type FormatException or OverflowException, value is known, and error is associated with a collection element or parameter. |
NonPropertyUnknownValueIsInvalid |
The supplied value is invalid. |
Exception is of type FormatException or OverflowException, value is unknown, and error is associated with a collection element or parameter. |
NonPropertyValueMustBeANumber |
The field must be a number. |
Error message HTML and tag helpers add for client-side validation of numeric formats. Visible in the browser if the field for a float (for example) collection element or action parameter does not have a correctly-formatted value. |
UnknownValueIsInvalid |
The supplied value is invalid for {0}. |
Exception is of type FormatException or OverflowException, value is unknown, and error is associated with a property. |
ValueIsInvalid |
The value '{0}' is invalid. |
Fallback error message HTML and tag helpers display when a property is invalid but the ModelErrors have nullErrorMessages. |
ValueMustBeANumber |
The field {0} must be a number. |
Error message HTML and tag helpers add for client-side validation of numeric formats. Visible in the browser if the field for a float (for example) property does not have a correctly-formatted value. |