【问题标题】:Data validation attributes and the custom resource manager数据验证属性和自定义资源管理器
【发布时间】:2013-08-05 20:15:43
【问题描述】:

我在搜索有关数据验证属性以及ErrorMessageResourceNameErrorMessageResourceType 的更多信息时发现了以下问题/答案:

How to use DataAnnotations ErrorMessageResourceName with custom Resource Solution

很遗憾,它没有我需要的信息。在答案中,提到了CustomResourceManager 的假定类:

[Required(
    ErrorMessageResourceType = typeof(CustomResourceManager), 
    ErrorMessageResourceName = "ResourceKey")]
public string Username { get; set; }

但是我找不到关于这个类的外观、它实现什么接口等的文档。我需要为验证失败提供自定义错误消息,但我找不到我需要这样做的文档。

【问题讨论】:

标签: c# validation attributes


【解决方案1】:

我今天遇到了同样的问题,因为我试图让具有实体框架和验证属性的 wpf 应用程序实现全球化。

我尝试了不同的解决方案,目前,我最终根据 Dave Sexton 在这篇文章中描述的示例创建了 CustomResourceManagerhttp://www.pcreview.co.uk/forums/load-resources-string-table-database-t2892227.html

基本上我已经实现了我的DatabaseResourceManagerDatabaseResourceSet 分别派生自ResourceManagerResourceSet,如下所示:

DatabaseResourceManager 实现:

public class DatabaseResourceManager : ResourceManager
{
    #region Singleton pattern http://msdn.microsoft.com/en-us/library/ff650316.aspx
    private static volatile DatabaseResourceManager instance;
    private static object syncRoot = new Object();

    private DatabaseResourceManager() : base() { }

    public static DatabaseResourceManager Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new DatabaseResourceManager();
                }
            }

            return instance;
        }
    }
    #endregion

    protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
    {
        if (culture == null)
            culture = CultureInfo.InvariantCulture;

        return new DatabaseResourceSet(culture);
    }
}

还有DatabaseResourceSet 实现:

public class DatabaseResourceSet : ResourceSet
{
    private readonly CultureInfo culture;
    private static readonly Dictionary<string, Hashtable> cachedResources = new Dictionary<string, Hashtable>();

    public DatabaseResourceSet(CultureInfo culture)
    {
        if (culture == null)
            throw new ArgumentNullException("culture");

        this.culture = culture;

        ReadResources();
    }

    protected override void ReadResources()
    {
        if (cachedResources.ContainsKey(culture.Name))
        // retrieve cached resource set
        {
            Table = cachedResources[culture.Name];
            return;
        }

        using (MyDatabaseContext db = new MyDatabaseContext())
        {
            var translations = from t in db.Translations
                       where t.CultureIso == culture.Name
                       select t;
            foreach (var translation in translations)
            {
                Table.Add(translation.Chave, translation.Valor);
            }
        }

        cachedResources[culture.Name] = Table;
    }
}

由于我的 DataBaseResourceManager 实现了单音模式,我可以轻松访问它并获取数据,如下所示:

public class LocalizedRequiredAttribute : RequiredAttribute
{
    public LocalizedRequiredAttribute() : base()
    {
    }

    public override string FormatErrorMessage(string name)
    {
        string localErrorMessage = DatabaseResourceManager.Instance.GetString(this.ErrorMessageResourceName) ?? ErrorMessage ?? "{0} is required"; //probably DataAnnotationsResources.RequiredAttribute_ValidationError would is a better option
        return string.Format(System.Globalization.CultureInfo.CurrentCulture, localErrorMessage, new object[] { name });
    }
}

现在的缺点:

就像 pcreview 帖子中所说,winforms 不接受这个DataBaseResourceManager,但在我的情况下,因为我使用的是 wpf,所以我没有这个问题(但由于重复ResourceManagerDictionaryResource) 。不知道您是否可以在 winforms 中注入资源管理器,但这超出了您的问题。 您已经知道的另一个缺点是我们必须派生所有使用的ValidationAttribute,以便使用FormatErrorMessageStringLengthAttributeRequiredAttributeRegularExpressionAttribute 等等。这很容易出错和笨拙。不幸的是,微软在这里没有给我们太多空间。

希望我能帮上忙,我可能会在未来查看此答案以分享我对此的发现。

问候

【讨论】:

    猜你喜欢
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多