Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get values out of object HtmlAttributes

Tags:

asp.net-mvc

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?

like image 422
chobo2 Avatar asked Aug 22 '09 06:08

chobo2


3 Answers

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.

like image 101
rrejc Avatar answered Oct 18 '22 04:10

rrejc


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

like image 43
Chtiwi Malek Avatar answered Oct 18 '22 03:10

Chtiwi Malek


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.

like image 42
Maxime Avatar answered Oct 18 '22 03:10

Maxime