Difference between anonymous class and IDictionary<string,object> for htmlAttributes in ASP.NET MVC?
Asked Answered
G

3

5

For example if you check these two extension methods the only difference is type of htmlAttributes so you can pass your htmlAttributes in two different ways:

public static MvcHtmlString TextBoxFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression,
    IDictionary<string, object> htmlAttributes);

public static MvcHtmlString TextBoxFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression,
    object htmlAttributes);

And use them in either of these ways:

@Html.TextBoxFor(model => model.TagLine,
    new { @placeholder = "We live to make art." })

@Html.TextBoxFor(model => model.TagLine,
    new Dictionary<string, object> { 
        { "placeholder", "We live to make art." } })

I have checked MVC source code and I know in the background they use same method, but the one which accepts the anonymous object uses HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes) to make the anonymous object a dictionary.

In my point of view, views are cleaner to use anonymous object. What do you think guys? Are there any drawbacks to using an anonymous object?

Gagliardi answered 16/11, 2011 at 23:36 Comment(0)
G
10

There's not too much difference, however using the anonymous object is a cleaner and more readable syntax for the caller, and now considered more standard practice. There might be a slight, negligible performance benefit to using IDictionary if you're a fan of micro-optimisation.

The IDictionary overload option has probably stuck since ASP.NET MVC 1.0 CTP days when C# 3.0 and anonymous objects were still quite new. Eilon Lipton's blog post proposing Using C# 3.0 Anonymous Types as Dictionaries gives some background.

Gough answered 17/11, 2011 at 0:6 Comment(1)
The dictionary overloads are useful in some cases where you already have a dictionary.Lumpkin
M
2

Chris answers all the thing.

I give 1 more reason why use IDictionary: Prior to MVC 3.0, you could not use anonymous object when you need a HTML5 attribute like "data-something" :D

Cheers

Malmo answered 17/11, 2011 at 0:15 Comment(2)
You can use this with underscore , like : @Html.TextBoxFor(model => model.TagLine, new { data_as_multiple = "true" })Gagliardi
From MVC 3.0 onwards you can use an underscore, e.g. new { data_something = "value" }, which will automatically be converted to a dash data-something="value"Gough
M
2

The IDictionary<string, object> is there for a special reason. If you want to adjust the htmlAttributes parameter in a extended function then this is possible. I have several extensions of the Html.TextBox function. I have for example a function thats called: TextBoxOrDisplayForNoDiaCritics. This function enables a TextBox or displays a disabled textbox. Additional it also removes DiaCritics from the textbox. I do this with a Javascript function. The event onchange fires on the input tag. So in this function I add that onchange event with the javascript function name to the htmlAttributes list. If I use a IDictionary thats easy but when I use an object that will be much harder.

So when you start your project its important to recognize what purpose your Html Helpers have to serve. In my case because I recognize the importance in my project I use IDictionary everywhere in my Project.

Moussaka answered 10/9, 2013 at 15:29 Comment(2)
This is exactly what I am trying to do. Do you pass in a dictionary object from your views (syntax is not as clean as passing in an anonymous object)? Or, if you pass in an anonymous object, how do you convert it to a dictionary so you can add additional attributes? Of course this is possible with reflection but this seems like a common enough scenario that I think they would have built a helper method in MVC for doing this conversion, but I haven't found it so farHilel
this is how I pass, does not look so clean but works: @Html.TextBoxWhenEmptyFor(model => model.UAccount, new Dictionary<string, object> { { ModelConstants.Style, ModelConstants.WidthMinZoekButton } }) another way: @Html.Partial("_LogoHeading", new { Logo = "Applicaties", Link = "Applicaties" }.ToExpando() ) because I want to pass properties and thats something that is otherwise not possible dynamically.Moussaka

© 2022 - 2024 — McMap. All rights reserved.