Извлечь отображаемое имя и описание атрибута из помощника HTML - PullRequest
8 голосов
/ 11 февраля 2011

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

1 Ответ

20 голосов
/ 11 февраля 2011

Отказ от ответственности: следующее работает только с 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
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...