如果我们需要支持另一个数据存储区,我的应用程序是在实现Repository模式的情况下设计的,并且我的代码将在未来为可选的依赖项注入做好准备。
我想为我的内容对象创建自定义验证属性。此属性应执行某种数据存储查找。例如,我需要我的内容有独特的slu ..要检查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(ErrorMessageResourceType = typeof (Localize), ErrorMessageResourceName = Resources.Localize.SlugRequired]
它不允许我们将其设置为动态内容。在第一种情况下,ContentType1在运行时得知,在第二种情况下,Resources.Localize.SlugRequired也在运行时得知(因为Culture设置是在运行时分配的)。
这真令人讨厌,并且无法实现这么多事情和实施方案。
所以,我的第一个问题是,如何摆脱这个错误? 我的第二个问题是,你是否认为我应该以任何方式重新设计我的验证码?
答案 0 :(得分:1)
摆脱错误的唯一方法就是按照它说的做,并将静态内容放在属性中。请记住,属性的用途是针对代码中的元数据,这些元数据专门用于在运行时查找有关代码的信息。实现这种动态将会破坏这一目的。
在我看来,如果你的slug是基于内容类型的动态,那么Slug属性应该是一个用内容类型初始化的对象。从发布的属性代码中,无需在构造函数中初始化存储库 - 因此将其移至IsValid()
方法并执行其中的所有操作,并进行一些检查以确保将值转换为Slug
并且ContentType
属性已设置。
如果您需要围绕属性执行大量动态实施方案,这可能表明存在设计问题。