我正在使用 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
首先它被派生类准确地用于格式化消息,其次是我们通过ErrorMessage属性设置错误消息的情况,第三是使用资源字符串的情况。根据您的情况,您可以使用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
您可以将基类ValidationAttribute的ErrorMessage属性用于所有 DataAnnotations 验证器。
例如:
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}")]
public int id;
也许会有所帮助。
对于ASP.NET Core验证,请参阅此页面,其中说明了如何使用服务引擎进行设置:
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);
}