23

In asp.net mvc I always see the built in html helpers they always have object htmlAttirbutes.

Then I usually do new {@id = "test", @class="myClass"}.

How do I extract a parameter like this in my own html helpers?

Like I am using "HtmlTextWriterTag" is their a way I can pass this whole object to the writer and it figured it out or what?

Also how does this work with big html helpers?

Like I am making a html helper and it uses all these tags.

Table
thead
tfooter
tbody
tr
td
a
img

Does that mean I have to make a html Attribute for each of these tags?

3 Answers 3

38

I usually do something like this:

   public static string Label(this HtmlHelper htmlHelper, string forName, string labelText, object htmlAttributes)
    {
        return Label(htmlHelper, forName, labelText, new RouteValueDictionary(htmlAttributes));
    }

    public static string Label(this HtmlHelper htmlHelper, string forName, string labelText,
                               IDictionary<string, object> htmlAttributes)
    {
        // Get the id
        if (htmlAttributes.ContainsKey("Id"))
        {
            string id = htmlAttributes["Id"] as string;
        }

        TagBuilder tagBuilder = new TagBuilder("label");
        tagBuilder.MergeAttributes(htmlAttributes);
        tagBuilder.MergeAttribute("for", forName, true);
        tagBuilder.SetInnerText(labelText);
        return tagBuilder.ToString();
    }

I suggest you to download the ASP.NET MVC source from the codeplex and take a look at the built in html helpers.

Sign up to request clarification or add additional context in comments.

1 Comment

turns out your example is more informative than the source. i couldn't figure out how the source worked as it was expected an IDictionary (like your label does) but i was trying to pass it the anonymous object. Once I saw you convert it to a RouteValueDictionary is made more sense.
6

you can transform the object htmlAttirbutes to an attribute/value string representation like this :

var htmlAttributes = new { id="myid", @class="myclass" };

string string_htmlAttributes = "";
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes))
{
  string_htmlAttributes += string.Format("{0}=\"{1}\" ", property.Name.Replace('_', '-'), HttpUtility.HtmlAttributeEncode(property.GetValue(htmlAttributes).ToString()));
}

PropertyDescriptor belong to the class System.ComponentModel

Comments

2

I use a mix of both methods (Chtiwi Malek and rrejc) proposed earlier and it works great.

With this method, it will convert data_id to data-id. It will also overwrite default attribute values you have set earlier.

using System.ComponentModel;
...


public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
    var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

    string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
    string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();

    if (String.IsNullOrEmpty(labelText))
        return MvcHtmlString.Empty;

    var label = new TagBuilder("label");
    label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(htmlAttributes))
    {
        // By adding the 'true' as the third parameter, you can overwrite whatever default attribute you have set earlier.
        label.MergeAttribute(prop.Name.Replace('_', '-'), prop.GetValue(htmlAttributes).ToString(), true);
    }
    label.InnerHtml = labelText;
    return MvcHtmlString.Create(label.ToString());
}

Note the comment about overwriting an attribute that has a default value in your code in the foreach.

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.