【问题标题】:How to replace standard DataAnnotations error messages如何替换标准 DataAnnotations 错误消息
【发布时间】:2010-02-01 12:45:34
【问题描述】:

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

【问题讨论】:

    标签: .net data-annotations


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢 Veton。你提到的最后一部分我完全错过了。
    • 我不明白应该如何命名资源文件(以及放置位置)以从 DataAnnotations.dll 覆盖 ResourceManager。
    【解决方案2】:

    您可以将基类 ValidationAttributeErrorMessage 属性用于所有 DataAnnotations 验证器。

    例如:

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

    也许会有所帮助。

    【讨论】:

    • 是的。但是有没有办法一次替换默认消息?
    • @FitzchakYitzchaki 你做到了吗?
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-06-17
      • 1970-01-01
      • 2010-11-13
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      相关资源
      最近更新 更多