代码之家  ›  专栏  ›  技术社区  ›  mare

在ASP.NET MVC 2中具有数据存储访问权限的自定义DataAnnotation属性

  •  2
  • mare  · 技术社区  · 14 年前

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

    我要为内容对象创建自定义验证属性。此属性应执行某种数据存储查找。例如,我需要我的内容有独特的鼻涕虫。要检查slug是否已经存在,我希望在基本内容对象中使用自定义dataannotation属性(而不是每次在控制器的插入操作中手动检查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)]
    

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

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

    如果在内置的必需属性上尝试执行此操作,则实际出现的错误与此相同:

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

    它不允许我们将其设置为动态内容。在第一种情况下,ContentType1在运行时已知,在第二种情况下,resources.localize.slugRequired也在运行时已知(因为区域性设置是在运行时分配的)。

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

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

    1 回复  |  直到 14 年前
        1
  •  1
  •   womp    14 年前

    消除错误的唯一方法是按照它所说的做,并将静态内容放在属性中。请记住,属性的用途是用于代码上的元数据,特别是用于在运行时查找有关代码的信息。使这一动态将破坏这一目的。

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

    如果需要围绕属性执行大量的动态实现场景,这可能表明存在设计问题。