Proveniebam
Proveniebam

Reputation: 47

MVC 5 using Attributes on Object to drive HtmlHelper unable to read

I have an object: Car with a several properties (Make, Model and Color). Each property has an assigned attribute (BilingualLabel).

I'm trying to write a strongly type htmlhelper for any type that has a BilingualLabel attribute assigned to it. I.e. I want to get hold of the "MakeFR" text that I attributed to the property in the Car class.

E.g.

[System.AttributeUsage(AttributeTargets.Property)]
public class BilingualLabel : System.Attribute
{
    private string _resourceCode = "";

    public BilingualLabel(string ResourceCode)
    {
        _resourceCode = ResourceCode;
    }
}

Then the car class:

public class Car
{
    [BilingualLabel("MakeFR")]
    public string Make { get; set; }

    [BilingualLabel("ModelFR")]
    public string Model { get; set; }

    [BilingualLabel("ColorFR")]
    public string Color { get; set; }

}

Now I come to the helper class and I can't seem to get to the attribute value I've set. I've shown two of the attempts I've tried. They both come back as empty attributes.

    public static MvcHtmlString BilingualLabelFor<T,E>(this HtmlHelper<T> htmlHelper, Expression<Func<T,E>> expression)
    {

        //get the Bilingual Label resource code

        //BilingualLabel attr =
        //    (BilingualLabel)Attribute.GetCustomAttribute(typeof(E), typeof(BilingualLabel));

        MemberExpression member = expression.Body as MemberExpression;
        PropertyInfo propInfo = member.Member as PropertyInfo;


        MvcHtmlString html = default(MvcHtmlString);

        return html;
    }

Upvotes: 0

Views: 313

Answers (1)

Kevin
Kevin

Reputation: 759

Right now your GetCustomAttribute call is trying to get a BilingualLabel off of the typeof(E) which will be a string in your case. You need to get the custom attribute based on the actual member instead of the types. Also, if you want to get the value you set back out of the custom attribute you need to set it to a public property.

Update attribute to have a public property:

[System.AttributeUsage(AttributeTargets.Property)]
public class BilingualLabel : System.Attribute
{
    public string ResourceCode { get; private set; }

    public BilingualLabel(string resourceCode)
    {
        this.ResourceCode = resourceCode;
    }
}

Then pull GetCustomAttribute off the member instead of type:

public static MvcHtmlString BilingualLabelFor<T,E>(this HtmlHelper<T> htmlHelper, Expression<Func<T,E>> expression)
{

    MvcHtmlString html = default(MvcHtmlString);

    MemberExpression memberExpression = expression.Body as MemberExpression;
    BilingualLabel attr = memberExpression.Member.GetCustomAttribute<BilingualLabel>();

    if (attr != null)
    {
      //Replace with actual lookup code to get Bilingual Label using attr.ResourceCode
      html = new MvcHtmlString(attr.ResourceCode);
    }

    return html;
}

Upvotes: 1

Related Questions