Для чего используется свойство DisplayAttribute.GroupName? - PullRequest
3 голосов
/ 11 июля 2011

Я пытаюсь определить действительные значения свойства DisplayAttribute.GroupName .

MSDN говорит:

Aзначение, которое используется для группировки полей в пользовательском интерфейсе.

, но я бы не назвал это исчерпывающим объяснением.Это заставляет меня думать, что GroupName можно использовать для создания групповых блоков вокруг определенных полей.Но затем замечание:

Не используйте это свойство, чтобы получить значение свойства GroupName.Вместо этого используйте метод GetDescription .Допустимо нулевое значение или пустая строка.

, кажется, противоречит этому.

Так, для чего это свойство и нужно ли его использовать (возможно, с пользовательским шаблоном или с пользовательскимModelMetadataProvider) для отображения групповых блоков вокруг моих полей?

Ответы [ 3 ]

1 голос
/ 11 июля 2011

В исходном коде MVC RTM нет признаков использования.

Замечание «GetDescription» может быть ошибкой копирования / вставки в документации (каждое свойство строки, похоже, имеет аналог GetXXX, который возвращает локализуемое значение), поэтому в данном случае это, скорее всего, будет «GetGroupName».

UPDATE: Я бы использовал это именно для этого: сгруппируйте поля, которые принадлежат друг другу с точки зрения пользовательского интерфейса. Так как это всего лишь аннотация данных в модели, она объявляет только, что эти поля принадлежат одной логической группе «как-то» в пользовательском интерфейсе, но конкретные детали представления зависят от «механизма пользовательского интерфейса», который отображает модель на основе метаданных. Я думаю, что наиболее значимый способ «визуализировать» это в пользовательском интерфейсе - это именно то, что вы сказали: упаковка сгруппированных полей в раздел или набор полей.

Конечно, могут быть будущие расширения MVC или другие пользовательские расширения, которые будут выполнять некоторую группировку в пользовательском интерфейсе «автоматически» (без написания специального кода, который проверяет метаданные и генерирует разделы) на основе этого свойства атрибута. Но я совершенно уверен, что такое расширение сделало бы нечто очень похожее на то, что вы сделали бы в настоящее время.

0 голосов
/ 27 апреля 2017

Как насчет этого !!! Должны работать:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    public static class DisplayGroup
    {
        public static MvcHtmlString DisplayGroupName(this HtmlHelper helper, string groupName)
        {
            return MvcHtmlString.Create(groupName);
        }

        public static MvcHtmlString DisplayGroupNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            var type = typeof(TModel);
            PropertyInfo propertyInfo = null;

            var member = (MemberExpression)expression.Body;
            var property = (PropertyInfo)member.Member;
            var name = property.Name;

            var metadataTypeInfo = type.GetCustomAttribute<MetadataTypeAttribute>();

            if (metadataTypeInfo != null)
            {
                var metadataType = metadataTypeInfo.MetadataClassType;
                propertyInfo = metadataType.GetProperties().Where(x => x.Name == name).FirstOrDefault();
                if (propertyInfo == null)
                {
                    propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
                }
            }
            else
            {
                propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
            }

            string output = "";

            var dattr = propertyInfo.GetCustomAttribute<DisplayAttribute>();
            if (dattr != null)
            {
                if (dattr.GroupName == null)
                {
                    output = propertyInfo.Name;
                }
                else
                {
                    output = dattr.GroupName;
                }
            }
            else
            {
                output = propertyInfo.Name;
            }

            return MvcHtmlString.Create(output);
        }

    }
}




public class MyModel
    {
        [Display(Name = "Number",GroupName="Invoice")]
        string InvNo { get; set; }
    }

, а затем просто напишите:

@Html.DisplayGroupNameFor(x => x.InvNo)

Примечание: NameSpace должно быть: System.Web.Mvc

Обновление: Круто то, что, если у вас есть класс MetaDataType, определенный для вашей аннотации данных, то это также будет работать, как и ожидалось.

0 голосов
/ 10 ноября 2011

В итоге я написал этот класс, чтобы сделать GroupName более доступным:

public class ExtendedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    public const string Key_GroupName = "GroupName";

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        ModelMetadata modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        DisplayAttribute displayAttribute = attributes.OfType<DisplayAttribute>().FirstOrDefault();

        if (displayAttribute != null)
            modelMetadata.AdditionalValues[ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName] = displayAttribute.GroupName;

        return modelMetadata;
    }
}

И этот метод расширения:

public static string GetGroupName(this ModelMetadata modelMetadata)
{
    if (modelMetadata.AdditionalValues.ContainsKey(ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName))
        return (modelMetadata.AdditionalValues[ExtendedDataAnnotationsModelMetadataProvider.Key_GroupName] as string);

    return null;
}

Источник: http://bradwilson.typepad.com/blog/2010/01/why-you-dont-need-modelmetadataattributes.html

...