asp.net MVC extending DataAnnotions

南楼画角 提交于 2019-12-06 04:34:43

问题


As well as DisplayName eg.

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

Html.LabelFor(model => model.Address1) 

I have a requirement to show tooltips eg.

[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) 

Can I extend the DisplayName DataAnnotation to do this? I can't see how it can be done.

Thanks!


回答1:


This is how I would do it. Time for some Champions League, I can clarify the code tomorrow if you want.

First a attribute:

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

    }

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

    }
}

And then a html helper to allow us to write 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("");
    }
}

Usage would then be this:

Your model:

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

And in your view:

<%= Html.ToolTipFor(x => x.FirstName) %>



回答2:


This should get you in the right direction. It's an extension method that grabs the model property you're passing in. (if you're using MVC3 you can replace MvcHtmlString.Create with 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("");

}



回答3:


You'd have to provide your own extension method for Html.LabelFor() (and the like for that matter) that would take into consideration tool tip attribute. It doesn't necessarily have to be derived from data annotations, since it's going to be custom handled.

You could of course inherit from DisplayName and then use that one. What you'd get doing this? You'd only have to provide a single attribute like DisplayNameWithTooltip that would then work as DisplayName and you'll use it in our code to get tooltip as well.

Additional edit

If your tooltips should be implemented by using HTML element's title attribute, then I didn't mean to use some special string syntax in DisplayName attribute but rather create a new attribute class that inherit DisplayNameAttribute:

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

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

    ...
}

And then use your custom attribute:

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

This way you won't have to parse your strings and other code will be able to use it as well since it inherits from DisplayName (because code probably uses calls IsAssignableFrom calls and similar).




回答4:


If you're using a metadata class, in my case as a result of a DB-first model, Alexn helper wont return the value of the Tooltip attribute, the helper below will.

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("");
}


来源:https://stackoverflow.com/questions/3707997/asp-net-mvc-extending-dataannotions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!