2012-02-21 9 views
5

Элемент DisplayAttribute в System.ComponentModel.DataAnnotations имеет свойство GroupName, которое позволяет логически группировать поля вместе в элементе управления пользовательским интерфейсом (например, в сетке свойств в WPF/WinForms).Как получить аннотацию данных GroupName из ModelMetadata

Я пытаюсь получить доступ к этим метаданным в приложении 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, даже с помощью метода расширения.

Вы можете реализовать своего собственного провайдера, который расширяет существующий, чтобы добавить поддержку для GroupName, что Brad Wilson explains in his blog.

Вы также можете написать свой собственный атрибут вместо Display(GroupName =) и реализовать интерфейс IMetadataAware, чтобы добавить имя группы в ModelMetadata.AdditionalValues.

+0

Спасибо, это похоже на то, что мне нужно. –

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

Альтернативой может быть использование ShortName свойство DisplayAttribute класса. Он является, выставленным ModelMetadata классом как ShortDisplayName.

Это не то, что вы ищете, но это позволит вам избежать создания другого класса атрибутов ... и, кроме того, вы можете воспользоваться возможностями локализации DisplayAttribute.

Смежные вопросы