如何替换标准DataAnnotations错误消息

时间:2010-02-01 12:45:35

标签: .net data-annotations

我正在使用System.ComponontModel.DataAnnotations来验证我的模型对象。如何替换消息标准属性(Required和StringLength)生成而不向每个消息提供ErrorMessage属性或对它们进行子类化?

3 个答案:

答案 0 :(得分:8)

撰写新帖子,因为我需要比评论提供更多的格式。

查看 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

在其他地方,让我们看一下派生构造函数,例如,Range Attribute:

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

答案 1 :(得分:6)

您可以对所有DataAnnotations验证程序使用基类 ValidationAttribute ErrorMessage 属性。

例如:

[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}")]
public int id;

也许它会有所帮助。

答案 2 :(得分:0)

有关 ASP.NET Core 验证,请参见this页,其中说明了如何使用服务引擎进行设置:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddDataAnnotationsLocalization(options => {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });
}

否则( WPF,WinForms或.NET Framework ),您可以使用反射来干扰DataAnnotations资源并将其替换为您自己的资源,然后可以根据您的应用程序的当前情况自动对其进行文化区分。文化。 有关更多信息,请参见this答案:

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);
}