2011-02-10 73 views
2

当我在ASP.NET MVC 3模型中使用DisplayAttribute时,它很快就变成了写它们的痛苦,因为我们必须对字符串进行硬编码或者从包含const strings(这是我所拥有的某个静态类引用字符串现在,见下文)。但即使这对我来说太过分了。自定义数据注解属性

我想拿出那被称为像[SimpleDisplay],它会含蓄地看着

  1. 类名构建资源字符串的属性,
  2. 属性名的属性被附加到。

这可能吗?

像这样的事情

public class Product { 

[SimpleDisplay] // it will take Product and Name and do something like this Product_Name 
public string Name { get; set; } 

} 

这是我想摆脱的,如果可能的话:

[Display(ResourceType = typeof(Resources.Localize), Name = ResourceStrings.product_prettyid)] 
    public virtual int PrettyId 
    { 
     get; 
     set; 
    } 

    [Display(ResourceType = typeof(Resources.Localize), Name = ResourceStrings.product_name)] 
    public virtual string Title 
    { 
     get; 
     set; 
    } 

现在我知道这是不可能的继承DisplayAttribute原因它的密封。我还有什么其他选择?它有意义吗?

回答

5

我会尝试创建一个标准属性和自定义DataAnnotationsModelMetadataProvider。您可以覆盖CreateMetadata方法,该方法得到IEnumerable<Attribute>。您应该搜索您的属性

attributes.OfType<SimpleDisplayAttribute>().FirstOrDefault(); 

并以任何您想要的方式填充模型元数据。

+0

谢谢,这是最好的方法。有关您的方法的更多详细信息,请参阅http://geekswithblogs.net/brians/archive/2010/06/14/asp.net-mvc-localization-displaynameattribute-alternatives-a-better-way.aspx – mare 2011-02-10 20:21:36

2

,如果我有一个正确的认识你的意思,你可能只是建立这样一个简单的自定义属性:

public class LocalizedDisplayNameAttribute : DisplayNameAttribute { 
    public LocalizedDisplayNameAttribute(string expression) : base(expression) { } 

    public override string DisplayName { 
     get { 
      try { 
       string[] vals = base.DisplayName.Split(','); 
       if(vals != null && vals.Length == 2) 
        return (string)HttpContext.GetGlobalResourceObject(vals[0].Trim(), vals[1].Trim()); 
      } catch {} 
      return "{res:" + base.DisplayName + "}"; 
     } 
    } 
} 

然后你可以使用它作为你的性的判定的属性。 MVC HTML扩展将吸取您的自定义属性。

[LocalizedDisplayName("LBL, lbl_name1")] 
public string[] Name1 { get; set; } 
+1

便于将属性合并到属性中。事实上,它使事情变得复杂,因为它依赖于硬编码参数而不是无参数(或强类型参数)。 – mare 2011-02-10 19:36:35