asp.net MVC расширяет DataAnnotions - PullRequest
       21

asp.net MVC расширяет DataAnnotions

4 голосов
/ 14 сентября 2010

А также DisplayName, например.

[DisplayName("Address line 1 ")]
public string Address1{get; set;}

Html.LabelFor(model => model.Address1) 

У меня есть требование показывать всплывающие подсказки, например.

[DisplayName("Address line 1 ")]
[ToolTip("The first line of your address as it appears on you bank statement")]
public string Address1{get; set;}

Html.LabelFor(model => model.Address1) 
Html.ToolTipFor(model => model.Address1) 

Могу ли я расширить аннотацию данных DisplayName для этого? Я не вижу, как это можно сделать.

Спасибо!

Ответы [ 4 ]

6 голосов
/ 14 сентября 2010

Вот как бы я это сделал.Время для какой-нибудь Лиги чемпионов, я могу уточнить код завтра, если хотите.

Сначала атрибут:

public class TooltipAttribute : DescriptionAttribute
{
    public TooltipAttribute()
        : base("")
    {

    }

    public TooltipAttribute(string description)
        : base(description)
    {

    }
}

А затем вспомогательный html, который позволит нам написать Html.TooltipFor ():

public static class HtmlHelpers
{
    public static MvcHtmlString ToolTipFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var exp = (MemberExpression)expression.Body;
        foreach (Attribute attribute in exp.Expression.Type.GetProperty(ex.Member.Name).GetCustomAttributes(false))
        {
            if (typeof(TooltipAttribute) == attribute.GetType())
            {
                return MvcHtmlString.Create(((TooltipAttribute)attribute).Description);
            }
        }
        return MvcHtmlString.Create("");
    }
}

Тогда будет использоваться:

Ваша модель:

public class User
{
    [Tooltip("This is the attribute for FirstName")]
    public string FirstName { get; set; }
}

А на ваш взгляд:

<%= Html.ToolTipFor(x => x.FirstName) %>
1 голос
/ 14 сентября 2010

Это должно привести вас в правильном направлении. Это метод расширения, который захватывает передаваемое вами свойство модели (если вы используете MVC3, вы можете заменить MvcHtmlString.Create на new HtmlString()

Html.ToolTipFor(m => m.Address1)

public static IHtmlString ToolTipFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
    MemberExpression ex = (MemberExpression)expression.Body;
    foreach(Attribute attribute in ex.Expression.Type.GetProperty(ex.Member.Name).GetCustomAttributes(true)) {
        if (typeof(TooltipAttribute) == attribute.GetType()) {
            return MvcHtmlString.Create(((TooltipAttribute)attribute).YourTooltipProperty);
        }
    }
    return MvcHtmlString.Create("");

}
1 голос
/ 14 сентября 2010

Вы должны предоставить свой собственный метод расширения для Html.LabelFor() (и тому подобное), который будет учитывать атрибут подсказки.Он не обязательно должен быть получен из аннотаций данных, поскольку он будет обрабатываться по своему усмотрению.

Конечно, вы можете наследовать от DisplayName и затем использовать эту.Что ты получишь при этом?Вам нужно будет предоставить только один атрибут, например DisplayNameWithTooltip, который будет работать как DisplayName, и вы также будете использовать его в нашем коде для получения всплывающей подсказки.

Дополнительное редактирование

Если ваши всплывающие подсказки должны быть реализованы с использованием атрибута title HTML-элемента, то я не хотел использовать какой-либо специальный синтаксис строки в атрибуте DisplayName, а скорее создал новый класс атрибута, который наследовал бы DisplayNameAttribute:

public class DisplayNameWithTooltipAttribute: DisplayNameAttribute
{
    public string Tooltip { get; private set; }

    public DisplayNameWithTooltipAttribute(string displayName, string tooltip) : base(displayName)
    {
        this.Tooltip = tooltip;
    }

    ...
}

А затем используйте свой пользовательский атрибут:

[DisplayNameWithTooltip("Some display name", "Some tooltip")]
public ActionResult SetSomething(SomeObj val) { ... }

Таким образом, вам не придется анализировать ваши строки, и другой код сможет использовать его также, поскольку он наследуется от DisplayName(потому что код, вероятно, использует звонки IsAssignableFrom звонки и тому подобное).

0 голосов
/ 29 марта 2013

Если вы используете класс метаданных, в моем случае в результате использования модели, основанной на DB, помощник Alexn не будет возвращать значение атрибута Tooltip, помощник ниже будет.

public static MvcHtmlString ToolTipFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
    var expressionBody = (MemberExpression)expression.Body;
    Type type = expressionBody.Expression.Type;

    MetadataTypeAttribute[] metadataAttributes = (MetadataTypeAttribute[])type.GetCustomAttributes(typeof(MetadataTypeAttribute), true);
    foreach (MetadataTypeAttribute metadataAttribute in metadataAttributes)
    {
        var metadataPropertyAttributes = metadataAttribute.MetadataClassType.GetProperty(expressionBody.Member.Name).GetCustomAttributes(false);
        foreach (Attribute metadataPropertyAttribute in metadataPropertyAttributes)
        {
            if (typeof(TooltipAttribute) == metadataPropertyAttribute.GetType())
            {
                return MvcHtmlString.Create(((TooltipAttribute)metadataPropertyAttribute).Description);
            }
        }
    }
    return MvcHtmlString.Create("");
}
...