I have my application designed with Repository pattern implemented and my code prepared for optional dependency injection in future, if we need to support another datastore.
如果我们需要支持另一个数据存储区,那么我的应用程序设计了Repository模式,并且我的代码将在未来为可选的依赖项注入做好准备。
I want to create a custom validation attribute for my content objects. This attribute should perform some kind of datastore lookup. For instance, I need my content to have unique slugs. To check if a Slug already exist, I want to use custom DataAnnotation attribute in my Base content object (instead of manually checking if a slug exists each time in my controller's Insert actions). Attribute logic would do the validation.
我想为我的内容对象创建自定义验证属性。此属性应执行某种数据存储查找。例如,我需要我的内容有独特的slu ..要检查Slug是否已经存在,我想在我的Base内容对象中使用自定义DataAnnotation属性(而不是每次在我的控制器的Insert操作中手动检查slug是否存在)。属性逻辑将进行验证。
So far I have come up with this:
到目前为止,我已经想出了这个:
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;
}
}
part of my Base content class:
我的基本内容类的一部分:
...
[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);
}
}
...
There's an error in line
有一个错误
[UniqueSlug(ContentType1)]
saying: "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type."
说:“属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式。”
Let me explain that I need to provide the ContentType1 parameter to the Constructor of UniqueSlug class because I use it in my data provider.
让我解释一下,我需要将ContentType1参数提供给UniqueSlug类的构造函数,因为我在我的数据提供程序中使用它。
It is actually the same error that appears if you try do to this on the built-in Required attribute:
如果您尝试对内置的Required属性执行此操作,则实际上出现的错误相同:
[Required(ErrorMessageResourceType = typeof (Localize), ErrorMessageResourceName = Resources.Localize.SlugRequired]
It does not allow us to set it to dynamic content. In the first case ContentType1 gets known at runtime, in the second case the Resources.Localize.SlugRequired also gets known at runtime (because the Culture settings are assigned at runtime).
它不允许我们将其设置为动态内容。在第一种情况下,ContentType1在运行时得知,在第二种情况下,Resources.Localize.SlugRequired也在运行时得知(因为Culture设置是在运行时分配的)。
This is really annoying and makes so many things and implementation scenarios impossible.
这真的很烦人,并且使得许多事情和实现方案变得不可能。
So, my first question is, how to get rid of this error? The second question I have, is whether you think that I should redesign my validation code in any way?
所以,我的第一个问题是,如何摆脱这个错误?我的第二个问题是,你是否认为我应该以任何方式重新设计验证码?
1 个解决方案
#1
1
The only way to get rid of the error is to do what it says, and put static content in your attributes. Remember that the purpose of attributes is for metadata on your code that is specifically for the purposes of looking up information about your code at runtime. Making this dynamic would defeat this purpose.
摆脱错误的唯一方法是按照它说的做,并将静态内容放在属性中。请记住,属性的用途是针对代码中的元数据,这些元数据专门用于在运行时查找有关代码的信息。实现这种动态会破坏这一目的。
It seems to me that if your slug is dynamic based on the content type, then the Slug property should be an object that is initialized with the content type. From the attribute code posted, there's no need to initialize your repository in the constructor anyway - so move it to the IsValid()
method and do everything in there, and just do a bit of checking to make sure the the value casts to a Slug
and that the ContentType
property is set.
在我看来,如果您的slug是基于内容类型的动态,那么Slug属性应该是使用内容类型初始化的对象。从发布的属性代码中,无需在构造函数中初始化您的存储库 - 因此将其移动到IsValid()方法并执行其中的所有操作,并进行一些检查以确保将值转换为Slug并设置了ContentType属性。
If you need to be doing a ton of dynamic implementation scenarios around attributes, this could be indicative of a design problem.
如果您需要围绕属性执行大量动态实现方案,这可能表明存在设计问题。
#1
1
The only way to get rid of the error is to do what it says, and put static content in your attributes. Remember that the purpose of attributes is for metadata on your code that is specifically for the purposes of looking up information about your code at runtime. Making this dynamic would defeat this purpose.
摆脱错误的唯一方法是按照它说的做,并将静态内容放在属性中。请记住,属性的用途是针对代码中的元数据,这些元数据专门用于在运行时查找有关代码的信息。实现这种动态会破坏这一目的。
It seems to me that if your slug is dynamic based on the content type, then the Slug property should be an object that is initialized with the content type. From the attribute code posted, there's no need to initialize your repository in the constructor anyway - so move it to the IsValid()
method and do everything in there, and just do a bit of checking to make sure the the value casts to a Slug
and that the ContentType
property is set.
在我看来,如果您的slug是基于内容类型的动态,那么Slug属性应该是使用内容类型初始化的对象。从发布的属性代码中,无需在构造函数中初始化您的存储库 - 因此将其移动到IsValid()方法并执行其中的所有操作,并进行一些检查以确保将值转换为Slug并设置了ContentType属性。
If you need to be doing a ton of dynamic implementation scenarios around attributes, this could be indicative of a design problem.
如果您需要围绕属性执行大量动态实现方案,这可能表明存在设计问题。