System.ComponontModel.DataAnnotationsを使用してモデルオブジェクトを検証しています。それぞれにErrorMessage属性を提供したり、サブクラス化したりせずに、標準属性(RequiredおよびStringLength)が生成するメッセージを置き換えるにはどうすればよいですか?
3 に答える
コメントよりも多くのフォーマットが必要なため、新しい投稿を作成します。
ValidationAttribute-検証属性の基本クラスを見てください。
検証エラーが発生した場合、エラーメッセージは次の方法で作成されます。
public virtual string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture, this.ErrorMessageString, new object[] { name });
}
次に、ErrorMessageStringプロパティを見てください。
protected string ErrorMessageString
{
get
{
if (this._resourceModeAccessorIncomplete)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, DataAnnotationsResources.ValidationAttribute_NeedBothResourceTypeAndResourceName, new object[0]));
}
return this.ResourceAccessor();
}
}
プロパティResourceAccessorは、次の場所から設定できます。
ValidationAttribute..ctor(Func<String>)
ValidationAttribute.set_ErrorMessage(String) : Void
ValidationAttribute.SetResourceAccessorByPropertyLookup() : Void
1つ目は、メッセージをフォーマットするためにdervidedクラスによって正確に使用され、2つ目はErrorMessageプロパティを介してエラーメッセージを設定する場合、3つ目はリソース文字列が使用される場合です。状況に応じて、ErrorMessageResourceNameを使用できます。
他の場所では、派生コンストラクターを見てみましょう。この例では、範囲属性:
private RangeAttribute()
: base((Func<string>) (() => DataAnnotationsResources.RangeAttribute_ValidationError))
{
}
ここで、 RangeAttribute_ValidationErrorはリソースからロードされます。
internal static string RangeAttribute_ValidationError
{
get
{
return ResourceManager.GetString("RangeAttribute_ValidationError", resourceCulture);
}
}
したがって、次のように、さまざまなtanデフォルトカルチャのリソースファイルを作成し、そこでメッセージを上書きできます。
http://www.codeproject.com/KB/aspnet/SatelliteAssemblies.aspx
http://msdn.microsoft.com/en-us/library/aa645513(VS.71).aspx
すべてのDataAnnotationsバリデーターに基本クラスValidationAttributeのErrorMessageプロパティを使用できます。
例えば:
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}")]
public int id;
多分それは助けになるでしょう。
ASP.NET Coreの検証については、次のページを参照してください。このページでは、サービスエンジンを使用してASP.NETCoreを設定する方法について説明しています。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
それ以外の場合(WPF、WinForms、または.NET Framework)、リフレクションを使用してDataAnnotationsリソースに干渉し、それらを独自のリソースに置き換えることができます。これにより、アプリの現在のカルチャに自動的に依存するようになります。詳細については、この回答を参照してください。
void InitializeDataAnnotationsCulture()
{
var sr =
typeof(ValidationAttribute)
.Assembly
.DefinedTypes
//ensure class name according to current .NET you're using
.Single(t => t.FullName == "System.SR");
var resourceManager =
sr
.DeclaredFields
//ensure field name
.Single(f => f.IsStatic && f.Name == "s_resourceManager");
resourceManager
.SetValue(null,
DataAnnotationsResources.ResourceManager, /* The generated RESX class in my proj */
BindingFlags.NonPublic | BindingFlags.Static, null, null);
var injected = resourceManager.GetValue(null) == DataAnnotationsResources.ResourceManager;
Debug.Assert(injected);
}