2012-02-21 42 views
5

System.ComponentModel.DataAnnotations中的DisplayAttribute具有GroupName属性,该属性允许您在UI控件(例如,WPF/WinForms中的属性网格)中将字段逻辑地组合在一起。如何从ModelMetadata检索GroupName数据注释

我想在ASP.NET MVC3应用程序中访问这个元数据,实质​​上是为了创建一个属性网格。如果我的模式是这样的:

public class Customer 
{ 
    [ReadOnly] 
    public int Id { get;set; } 

    [Display(Name = "Name", Description = "Customer's name", GroupName = "Basic")] 
    [Required(ErrorMessage = "Please enter the customer's name")] 
    [StringLength(255)] 
    public string Name { get;set; } 

    [Display(Name = "Email", Description = "Customer's primary email address", GroupName = "Basic")] 
    [Required] 
    [StringLength(255)] 
    [DataType(DataType.Email)] 
    public string EmailAddress { get;set; } 

    [Display(Name = "Last Order", Description = "The date when the customer last placed an order", GroupName = "Status")] 
    public DateTime LastOrderPlaced { get;set; } 

    [Display(Name = "Locked", Description = "Whether the customer account is locked", GroupName = "Status")] 
    public bool IsLocked { get;set; } 
} 

,我的看法是这样的:

@model Customer 

<div class="edit-customer"> 
    @foreach (var property in ViewData.ModelMetadata.Properties.Where(p => !p.IsReadOnly).OrderBy(p => p.Order)) 
    { 
     <div class="editor-row"> 
      @Html.DevExpress().Label(settings => 
       { 
        settings.AssociatedControlName = property.PropertyName; 
        settings.Text = property.DisplayName; 
        settings.ToolTip = property.Description; 
       }).GetHtml() 
      <span class="editor-field"> 
       @Html.DevExpress().TextBox(settings => 
        { 
         settings.Name = property.PropertyName; 
         settings.Properties.NullText = property.Watermark; 
         settings.Width = 200; 
         settings.Properties.ValidationSettings.RequiredField.IsRequired = property.IsRequired; 
         settings.ShowModelErrors = true; 
        }).Bind(ViewData[property.PropertyName]).GetHtml() 
      </span> 
     </div> 
    } 
</div> 

然后形式奠定了基础非常漂亮,元数据,带标签的图标提示,水印等全部拔掉脱离模型的元数据; ,我希望能够将这些项目组合在一起,例如每个组中的<fieldset>。有没有人知道如何从元数据中获取GroupName,而不是为ModelMetadata编写扩展方法?

回答

6

GroupName没有被DataAnnotationsModelMetadataProvider解析。因此,即使使用扩展方法,也无法从ModelMetadata对象中找到它。

你可以实现自己的供应商,扩展了现有的以添加组名的支持,布拉德·威尔逊explains in his blog

您也可以编写自己的属性,而不是使用Display(GroupName =)并实现IMetadataAware接口以将组名添加到ModelMetadata.AdditionalValues

+0

谢谢,那看起来就像我需要的东西。 – 2012-02-22 01:28:14

1

您还可以使用这个扩展方法:

public static class ModelMetadataExtensions 
{ 
    public static T GetPropertyAttribute<T>(this ModelMetadata instance) 
    where T : Attribute 
    { 
    var result = instance.ContainerType 
     .GetProperty(instance.PropertyName) 
     .GetCustomAttributes(typeof(T), false) 
     .Select(a => a as T) 
     .FirstOrDefault(a => a != null); 

    return result; 
    } 
} 

然后

var display= this.ViewData.ModelMetadata 
    .GetPropertyAttribute<DisplayAttribute>(); 

var groupName = display.Groupname; 
0

另一种可能是使用DisplayAttribute类的ShortName财产。它的ModelMetadata类暴露的ShortDisplayName属性。

这不正是你要找的东西,但它可以让你避免造成另一个属性类...以及最重要的是,你可以采取的DisplayAttribute的定位能力优势。