5

I've extended the HTML helper with a method that needs an attribute value from the property of the model. So I've defined a custom attribute as such.

    public class ChangeLogFieldAttribute : Attribute {
        public string FieldName { get; set; }
    }

It's used like this in my model.

    [Display(Name = "Style")]
    [ChangeLogField(FieldName = "styleid")]
    public string Style { get; set; }

In my helper method, I've got the following code to get the FieldName value of my attribute, if the attribute is used for the property.

        var itemName = ((MemberExpression)ex.Body).Member.Name;

        var containerType = html.ViewData.ModelMetadata.ContainerType;
        var attribute = ((ChangeLogFieldAttribute[])containerType.GetProperty(html.ViewData.ModelMetadata.PropertyName).GetCustomAttributes(typeof(ChangeLogFieldAttribute), false)).FirstOrDefault();
        if (attribute != null) {
            itemName = attribute.FieldName;
        }

However, when I reach this code, I get an exception because the containerType is null.

I'm not sure if I'm doing any of this correct, but I pulled from about 4 different sources to get this far. If you could suggest a fix to my problem or an alternative, I'd be grateful.

Thanks.

UPDATE WITH SOLUTION

I used Darin Dimitrov's solution, although I had to tweak it some. Here is what I added. I had to check for the existence of the attribute metatdata and all was good.

        var fieldName = ((MemberExpression)ex.Body).Member.Name;

        var metadata = ModelMetadata.FromLambdaExpression(ex, html.ViewData);
        if (metadata.AdditionalValues.ContainsKey("fieldName")) { 
            fieldName = (string)metadata.AdditionalValues["fieldName"];
        }
1
  • To get a property name, you can use metadata.PropertyName instead of ((MemberExpression)ex.Body).Member.Name. This doesn't work for field names, though, and I don't see any .FieldName or .MemberName. Commented May 2, 2012 at 23:17

1 Answer 1

11

You could make the attribute metadata aware:

public class ChangeLogFieldAttribute : Attribute, IMetadataAware
{
    public string FieldName { get; set; }

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

and then inside the helper:

var metadata = ModelMetadata.FromLambdaExpression(ex, htmlHelper.ViewData);
var fieldName = metadata.AdditionalValues["fieldName"];
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.