Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to access additional metadata info from a custom display or editor template?

I am aware that in a custom display or editor template I can get metadata about the model via ViewData.ModelMetadata, which has properties that indicate whether certain metadata attributes have been defined for the property, such as IsRequired, DisplayName, and so on. But is there anyway I can access custom metadata I've added to the property via custom attributes?

For example, say in my view I have a property like so:

[UIHint("Whizbang")]
[SomeAttribute("foobar")]
public string LeftWhizbang { get; set; }

And I have a custom display template named Whizbang.cshtml with the following content:

@model string

Left Whizbang Value: @Model

What I'd like to do is be able to determine whether the property LeftWhizbang is decorated with the attribute SomeAttribute and, if so, I'd like to access the attribute's Message property (say), namely the value "foobar".

I'd like to be able to do something like this in my template:

@model string

Left Whizbang Value: @Model

@{
    SomeAttributeAttribute attr = ViewData.ModelMetadata.GetAttributes(...);
    if (attr != null)
    {
        <text>... and the value is @attr.Message</text>
    }
}

Is this at all possible, or am I looking down a dead end?

like image 762
Scott Mitchell Avatar asked Oct 06 '11 23:10

Scott Mitchell


1 Answers

Sure. First you'll need your attribute which implements IMetadataAware so that DataAnnotationsModelMetadataProvider knows about it

public class TooltipAttribute : Attribute, IMetadataAware {
    public TooltipAttribute(string tooltip) {
        this.Tooltip = tooltip;
    }

    public string Tooltip { get; set; }

    public void OnMetadataCreated(ModelMetadata metadata) {
        metadata.AdditionalValues["Tooltip"] = this.Tooltip;
    }
}

You can then access the attribute by creating a helper method:

public static IHtmlString TooltipFor<TModel, TValue>(
                             this HtmlHelper<TModel> html,
                             Expression<Func<TModel, TValue>> expression) {
    var data = ModelMetadata.FromLambdaExpression<TModel, TValue>(expression, html.ViewData);
    if (data.AdditionalValues.ContainsKey("Tooltip"))
        return new HtmlString((string)data.AdditionalValues["Tooltip"]);

    return new HtmlString("");
}
like image 145
Buildstarted Avatar answered Nov 05 '22 06:11

Buildstarted