【问题标题】:Custom DataAnnotation attribute with datastore access in ASP.NET MVC 2在 ASP.NET MVC 2 中具有数据存储访问权限的自定义 DataAnnotation 属性
【发布时间】:2010-04-05 17:26:10
【问题描述】:

如果我们需要支持另一个数据存储,我的应用程序设计实现了存储库模式,并且我的代码为将来可选的依赖注入做好了准备。

我想为我的内容对象创建一个自定义验证属性。该属性应该执行某种数据存储查找。例如,我需要我的内容有独特的 slug。要检查 Slug 是否已经存在,我想在我的 Base 内容对象中使用自定义 DataAnnotation 属性(而不是每次在我的控制器的 Insert 操作中手动检查是否存在 slug)。属性逻辑将进行验证。

到目前为止,我想出了这个:

public class UniqueSlugAttribute : ValidationAttribute
{
    private readonly IContentRepository _repository;

    public UniqueSlugAttribute(ContentType contentType)
    {
        _repository = new XmlContentRepository(contentType);
    }

    public override bool IsValid(object value)
    {
        if (string.IsNullOrWhiteSpace(value.ToString()))
        {
            return false;
        }

        string slug = value.ToString();
        if(_repository.IsUniqueSlug(slug))
            return true;

        return false;
    }
}

我的基本内容类的一部分:

...
        [DataMember]
        public ContentType ContentType1 { get; set; }

        [DataMember]
        [Required(ErrorMessageResourceType = typeof (Localize), ErrorMessageResourceName = "Validation_SlugIsBlank")]
        [UniqueSlug(ContentType1)]
        public string Slug
        {
            get { return _slug; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                    _slug = Utility.RemoveIllegalCharacters(value);
            }
        }
...

一行有错误

    [UniqueSlug(ContentType1)]

说:“属性参数必须是属性参数类型的常量表达式、typeof表达式或数组创建表达式。”

让我解释一下,我需要将 ContentType1 参数提供给 UniqueSlug 类的构造函数,因为我在数据提供程序中使用它。

如果您尝试对内置的Required属性执行此操作,实际上会出现相同的错误:

[Required(ErrorMessageResourceType = typeof (Localize), ErrorMessageResourceName = Resources.Localize.SlugRequired]

它不允许我们将其设置为动态内容。在第一种情况下 ContentType1 在运行时获知,在第二种情况下 Resources.Localize.SlugRequired 在运行时也获知(因为文化设置是在运行时分配的)。

这真的很烦人,让很多事情和实现场景变得不可能。

那么,我的第一个问题是,如何摆脱这个错误? 我的第二个问题是,您是否认为我应该以任何方式重新设计我的验证代码?

【问题讨论】:

    标签: asp.net-mvc validation data-annotations


    【解决方案1】:

    摆脱错误的唯一方法是按照它所说的去做,并将静态内容放入您的属性中。请记住,属性的用途是用于代码上的元数据,专门用于在运行时查找有关代码的信息。制造这种动力会破坏这个目的。

    在我看来,如果您的 slug 基于内容类型是动态的,那么 Slug 属性应该是一个使用内容类型初始化的对象。从发布的属性代码来看,无论如何都不需要在构造函数中初始化您的存储库 - 因此将其移至 IsValid() 方法并在其中执行所有操作,然后进行一些检查以确保将值转换为 @ 987654322@ 并且设置了ContentType 属性。

    如果您需要围绕属性执行大量动态实施方案,这可能表明存在设计问题。

    【讨论】:

    • 我不在 Slug 生成中使用 ContentType。我只是使用 ContentType 来区分内容对象类型(Page、Section、TabGroup、Tab),它们有共同的基类 BaseContentObject。我的数据提供程序中还使用 ContentType 属性将内容保存到 App_Data 中的适当子文件夹,例如 ~/App_data/Page/page-slug.xml 或 ~/App_Data/TabGroup/tabgroup-slug.xml。 Slug 在其各自的内容文件夹中是唯一的,但可以跨文件夹重复。例如, someslug.xml 可以存在于 Page 文件夹和 TabGroup 文件夹中。我的数据提供者会处理这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多