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

Я создаю собственный помощник 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 с именем и описанием, но я не понимаю, как извлечь его с помощью переменной метаданных в приведенном выше коде?


person Banshee    schedule 11.02.2011    source источник


Ответы (1)


Отказ от ответственности: следующее работает только с 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
    ...
}
person Darin Dimitrov    schedule 11.02.2011
comment
Спасибо! Но это не работает, DisplayName и Description равны нулю? Обратите внимание, что это в MVC2, а не в MVC3. Если я правильно понял, ваше решение будет работать только в MVC3? - person Banshee; 12.02.2011
comment
@SnowJim, да, есть пара свойств, которые по умолчанию невозможно заполнить DataAnnotations в .NET 3.5, и Description - одно из них. В .NET 4.0 это должно работать. - person Darin Dimitrov; 12.02.2011
comment
@SnowJim, пожалуйста, посмотрите мое ОБНОВЛЕНИЕ для обходного пути в ASP.NET MVC 2. - person Darin Dimitrov; 12.02.2011
comment
Это один из самых полных ответов, которые я встречал, поэтому +1. Спасибо @DarinDimitrov! - person RvdV79; 14.08.2013