views:

2784

answers:

1

When writing an htmlhelper extension if I want to support the similarly structured ctors for my htmlhelper extension method, I use RouteValueDictionary as follows:

public static string ListBoxDict(this HtmlHelper htmlHelper, 
                                 string name, 
                                 object value, 
                                 object htmlAttributes)
{
    return ListBoxDict(htmlHelper, 
                       name, 
                       value, 
                       ((IDictionary<string, object>)
                           new RouteValueDictionary(htmlAttributes)));
}

My question really is why the need for RouteValueDictionary ... I know you can't just cast the htmlAttributes to IDictionary<string, object> ... though I'm not sure why and that might be where I'm confused. Shouldn't RouteValueDictionary be to do with Routing and therefore nothing to do with HtmlHelper methods? Like I say, I'm probably missing the point so I'd be glad if someone could tell me what I've missed.

Cheers...

edit: in response to Dan's answer -->

I was just following what I had seen in use in the mvc source code for input helpers...

  • see "src\SystemWebMvc\Mvc\Html\InputExtensions.cs"

It does as follows:

public static string TextBox(this HtmlHelper htmlHelper, 
                             string name, 
                             object value, 
                             object htmlAttributes)
{
    return TextBox(htmlHelper, 
                   name, 
                   value,
                   new RouteValueDictionary(htmlAttributes))
}

Clearly a shortcut but is it a bastardization or is it ok to do it?

+2  A: 

I would strongly recommend looking at Rob Conery's blog post about something like this.

The meat and veg of it is this:

Codedump:

public static string ToAttributeList(this object list)
{
  StringBuilder sb = new StringBuilder();
  if (list != null)
  {
    Hashtable attributeHash = GetPropertyHash(list);
    string resultFormat = "{0}=\"{1}\" ";
    foreach (string attribute in attributeHash.Keys)
    {
      sb.AppendFormat(resultFormat, attribute.Replace("_", ""), 
          attributeHash[attribute]);
    }
  }
  return sb.ToString();
}

public static string ToAttributeList(this object list,
                                     params object[] ignoreList)
{
  Hashtable attributeHash = GetPropertyHash(list);

  string resultFormat = "{0}=\"{1}\" ";
  StringBuilder sb = new StringBuilder();
  foreach (string attribute in attributeHash.Keys)
  {
    if (!ignoreList.Contains(attribute))
    {
      sb.AppendFormat(resultFormat, attribute, 
          attributeHash[attribute]);
    }
  }
  return sb.ToString();
}

public static Hashtable GetPropertyHash(object properties)
{
  Hashtable values = null;

  if (properties != null)
  {
    values = new Hashtable();
    PropertyDescriptorCollection props = 
        TypeDescriptor.GetProperties(properties);

    foreach (PropertyDescriptor prop in props)
    {
      values.Add(prop.Name, prop.GetValue(properties));
    }
  }
  return values;
}

Usage:

public static string ListBoxDict(this HtmlHelper htmlHelper, 
                                 string name, 
                                 object value, 
                                 object htmlAttributes)
{
    return htmlHelper.ListBoxDict(name,
                                  value,
                                  htmlAttributes.ToAttributeList()));
}

What .ToAttributeList() does is convert your htmlAttribute object to

name = "value"

Hope this makes sense.

Dan Atkinson
Thanks Dan, that looks interesting and I'll take a look. I've edited my question because I hadn't said that I was following what was already in place in the mvc framework helpers
Owen Thomson
Huh. I was looking for this again for another project and found my own answer! What luck!
Dan Atkinson
+1 Thanks, helped me out on a project...
Alexander