DataAnnotation 属性伙伴类陌生 - ASP.NET MVC
假设这个 POCO 类是由 EntityFramework T4 模板自动生成的(没有也不能以任何方式手动编辑):
public partial class Customer
{
[Required]
[StringLength(20, ErrorMessage = "Customer Number - Please enter no more than 20 characters.")]
[DisplayName("Customer Number")]
public virtual string CustomerNumber { get;set; }
[Required]
[StringLength(10, ErrorMessage = "ACNumber - Please enter no more than 10 characters.")]
[DisplayName("ACNumber")]
public virtual string ACNumber{ get;set; }
}
请注意,“ACNumber”是一个命名错误的数据库字段,因此自动生成器无法生成正确的显示名称和错误消息应该是“帐号”。
因此,我们手动创建这个好友类来添加无法自动生成的自定义属性:
[MetadataType(typeof(CustomerAnnotations))]
public partial class Customer { }
public class CustomerAnnotations
{
[NumberCode] // This line does not work
public virtual string CustomerNumber { get;set; }
[StringLength(10, ErrorMessage = "Account Number - Please enter no more than 10 characters.")]
[DisplayName("Account Number")]
public virtual string ACNumber { get;set; }
}
其中 [NumberCode] 是一个基于正则表达式的简单属性,仅允许数字和连字符:
[AttributeUsage(AttributeTargets.Property)]
public class NumberCodeAttribute: RegularExpressionAttribute
{
private const string REGX = @"^[0-9-]+$";
public NumberCodeAttribute() : base(REGX) { }
}
现在,当我加载页面时, DisplayName 属性可以正常工作 - 它显示伙伴类的显示名称,而不是生成的类。
StringLength 属性无法正常工作 - 它显示来自生成的类的错误消息(“ACNumber”而不是“Account Number”)。
但是伙伴类中的 [NumberCode] 属性甚至没有应用于 AccountNumber 属性:
foreach (ValidationAttribute attrib in prop.Attributes.OfType<ValidationAttribute>())
{
// This collection correctly contains all the [Required], [StringLength] attributes
// BUT does not contain the [NumberCode] attribute
ApplyValidation(generator, attrib);
}
为什么 prop.Attributes.OfType
集合不包含 [NumberCode] 属性? NumberCode 继承了 RegularExpressionAttribute,而 RegularExpressionAttribute 又继承了 ValidationAttribute,因此它应该在那里。
如果我手动将 [NumberCode] 属性移至自动生成的类,则它将包含在 prop.Attributes.OfType
集合中。
所以我不明白的是,为什么当伙伴类中的其他属性起作用时,这个特定属性在伙伴类中不起作用。以及为什么这个属性在自动生成的类中起作用,但在伙伴中不起作用。有什么想法吗?
另外,为什么 DisplayName 会被好友覆盖,而 StringLength 不会被覆盖?
Given this POCO class that was automatically generated by an EntityFramework T4 template (has not and can not be manually edited in any way):
public partial class Customer
{
[Required]
[StringLength(20, ErrorMessage = "Customer Number - Please enter no more than 20 characters.")]
[DisplayName("Customer Number")]
public virtual string CustomerNumber { get;set; }
[Required]
[StringLength(10, ErrorMessage = "ACNumber - Please enter no more than 10 characters.")]
[DisplayName("ACNumber")]
public virtual string ACNumber{ get;set; }
}
Note that "ACNumber" is a badly named database field, so the autogenerator is unable to generate the correct display name and error message which should be "Account Number".
So we manually create this buddy class to add custom attributes that could not be automatically generated:
[MetadataType(typeof(CustomerAnnotations))]
public partial class Customer { }
public class CustomerAnnotations
{
[NumberCode] // This line does not work
public virtual string CustomerNumber { get;set; }
[StringLength(10, ErrorMessage = "Account Number - Please enter no more than 10 characters.")]
[DisplayName("Account Number")]
public virtual string ACNumber { get;set; }
}
Where [NumberCode] is a simple regex based attribute that allows only digits and hyphens:
[AttributeUsage(AttributeTargets.Property)]
public class NumberCodeAttribute: RegularExpressionAttribute
{
private const string REGX = @"^[0-9-]+$";
public NumberCodeAttribute() : base(REGX) { }
}
NOW, when I load the page, the DisplayName attribute works correctly - it shows the display name from the buddy class not the generated class.
The StringLength attribute does not work correctly - it shows the error message from the generated class ("ACNumber" instead of "Account Number").
BUT the [NumberCode] attribute in the buddy class does not even get applied to the AccountNumber property:
foreach (ValidationAttribute attrib in prop.Attributes.OfType<ValidationAttribute>())
{
// This collection correctly contains all the [Required], [StringLength] attributes
// BUT does not contain the [NumberCode] attribute
ApplyValidation(generator, attrib);
}
Why does the prop.Attributes.OfType<ValidationAttribute>()
collection not contain the [NumberCode] attribute? NumberCode inherits RegularExpressionAttribute which inherits ValidationAttribute so it should be there.
If I manually move the [NumberCode] attribute to the autogenerated class, then it is included in the prop.Attributes.OfType<ValidationAttribute>()
collection.
So what I don't understand is why this particular attribute does not work in when in the buddy class, when other attributes in the buddy class do work. And why this attribute works in the autogenerated class, but not in the buddy. Any ideas?
Also why does DisplayName get overriden by the buddy, when StringLength does not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我注意到您的 NumberCodeAttribute 未在 AttributeUsage 属性中指定 AllowMultiple=True 。该参数的默认值(如果未指定)为 false。尝试添加它,它应该会出现。
I noticed that your NumberCodeAttribute doesn't specify AllowMultiple=True in the AttributeUsage attribute. The default for that parameter (if it isn't specified) is false. Try adding that on and it should appear.
我使用 VS2008 和 MVC2 重新创建了您的代码,它对我来说工作得很好。
I recreated your code using VS2008 and MVC2 and it worked fine for me.