Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Извлечение отображаемого имени и атрибута описания из помощника HTML

Автор вопроса: BansheeОтветов: 1

Я создаю собственный помощник HTML.LabelFor, который выглядит так:

public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> self, Expression<Func<TModel, TValue>> expression, Boolean showToolTip)
{
  var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
  ...
}

Чтобы получить правильное имя для свойства, я использую следующий код:

metadata.DisplayName

И по свойству класса ModelView я получил:

[DisplayName("Titel")]

Проблема в том, что мне тоже нужно описание. Существует атрибут Display с именем и описанием, но я не понимаю, как извлечь его с помощью переменной метаданных в приведенном выше коде?

attributesreflectionhtml-helper

Ответы

Ответ 1 · рейтинг 20 · Darin Dimitrov

Отказ от ответственности: следующее работает только с ASP.NET MVC 3 (см. обновление внизу, если вы используете предыдущие версии)

Предполагая следующую модель:

public class MyViewModel
{
    [Display(Description = "some description", Name = "some name")]
    public string SomeProperty { get; set; }
}

И следующий вид:

<%= Html.LabelFor(x => x.SomeProperty, true) %>

Внутри вашего собственного помощника вы можете получить эту информацию из метаданных:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> self,
    Expression<Func<TModel, TValue>> expression,
    bool showToolTip
)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
    var description = metadata.Description; // will equal "some description"
    var name = metadata.DisplayName; // will equal "some name"
    // TODO: do something with the name and the description
    ...
}

Примечание. Наличие [DisplayName("foo")] и [Display(Name = "bar")] в одном и том же свойстве модели является избыточным, а имя, используемое в атрибуте [Display], имеет приоритет в metadata.DisplayName.


ОБНОВИТЬ:

Мой предыдущий ответ не будет работать с ASP.NET MVC 2.0. Есть пара свойств, которые невозможно заполнить по умолчанию DataAnnotations в .NET 3.5, и Description - одно из них. Чтобы добиться этого в ASP.NET MVC 2.0, вы можете использовать собственный поставщик метаданных модели:

public class DisplayMetaDataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType,
        Func<object> modelAccessor,
        Type modelType,
        string propertyName
    )
    {
        var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

        var displayAttribute = attributes.OfType<DisplayAttribute>().FirstOrDefault();
        if (displayAttribute != null)
        {
            metadata.Description = displayAttribute.Description;
            metadata.DisplayName = displayAttribute.Name;
        }
        return metadata;
    }
}

который вы бы зарегистрировали в Application_Start:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ModelMetadataProviders.Current = new DisplayMetaDataProvider();
}

и тогда помощник должен работать как положено:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> self,
    Expression<Func<TModel, TValue>> expression,
    bool showToolTip
)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
    var description = metadata.Description; // will equal "some description"
    var name = metadata.DisplayName; // will equal "some name"
    // TODO: do something with the name and the description
    ...
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы