views:

379

answers:

2

In a DTO object I'd like to hard code the label description for the rendered html text box so that I can have an html helper function like TextBoxWithLabel where I pass only the object and it automatically creates the label taken from the description attributes.

  public class MessageDTO
{
    public int id { get; set; }
    [Description("Insert the title")]
    public string Title { get; set; }
    [Description("Description")]
    public string Body { get; set; }
}

Then in my view page I would like to call:

<%=Html.TextBoxWithLabel<string>(dto.Title)%>

and get the in the rendered view

<label for="Title">Insert the title :</label>
<input id="Title" type="text" value="" name="Title"/>

I think to achieve this I should use reflection. Is it correct or it will slow down the view rendering?

A: 

Yes, you would need to read the description with reflection. Yes, that would slow down rendering... a little. Only profiling would tell you if the slowdown is enough to be worth worrying about. Probably the cost of rendering the rest of the page is higher, so if rendering speed is an issue, caching the whole page might make more sense than trying to optimize reading the Description attribute.

When you do this, bear in mind that DescriptionAttribute can take a resource identifier as well as a literal caption.

Craig Stuntz
+3  A: 

Your best bet would to be write an extension method on the HtmlHelper that would use reflection to get the attributes from the property. The only problem is that passing dto.Title would pass the value of the string, and you would need the property. I think you would probably need to pass the object and the property name as a string.

public static string TextBoxWithLabel<T>(this HtmlHelper base, object obj, string prop)
{
    string label = "";
    string input = "<input type=\"text\" value\"\" name=\"" + prop + "\"";

    Type t = sender.GetType();
    PropertyInfo pi = t.GetProperty(prop);
    object[] array = pi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (array.Length != 0)
        label = "<label>" + ((DescriptionAttribute)array[0]).Value + "</label>";
    return label + input;
}

The exact syntax of the helper may be wrong, because I'm doing this from memory, but you get the jist. Then just import the namespace of your extension method into the page and you can use this function.

Matt Murrell