ASP.NET MVC - How to set HtmlAttributes programmatically in Razor HTML helpers A short guide explaining how to dynamically set the HtmlAttributes in Html.TextBoxFor, LabelFor and other Razor HTML helpers

ASP.NET MVC - Aggiungere uno o più percorsi di ricerca predefiniti per le View

If you're a seasoned ASP.NET MVC developer, you most likely already know that most Razor HTML helpers let you use an anonymous object in a parameter called htmlAttributes. As the name says, its members will be used to generate the HTML attribures of that element.

For example, this:

Will become this:

The only two notable exceptions are Html.EditorFor and Html.DisplayFor, which uses a slightly different syntax:

As we can see, even though they're using an anonymous object into an anonymous object container, the overall logic is basically the same.

It's worth noting that this "enhanced" capability for the two above methods has been added in ASP.NET 5.1 to ease the life of most developers. For the sake of simplicity, we'll stick to this post topic and avoid explaining this specific behaviour: to read the whole story, we strongly suggest to read this official MS post. For now, let's just assume that we're all using ASP.NET MVC 5.1 (or above).

As you probably know, anonymous types are created by the compiler at runtime level, so they aren't exactly handy when we want to modify them at execution level...  to put it in other words, it just cannot be done.

The Problem

So, what if we need to assign these HTML attributes programmatically and dinamically?

As a matter of fact, we can do a lot of things using variables, inline methods, conditional blocks or other viable strategies:

However, there are scenarios where we need to conditionally add (or skip) certain attributes as a whole. The perfect example of this is a TextBoxFor element which we would like to set readonly only in some circumstances. The readonly attribute is a tricky one, because it works as a property setting and not as a valued attribute. Its mere presence is enough to set the element read-only, despite of its value: this basically means that there's no way to explicitly set it to FALSE.

Pretty neat, isn't it? To know more about it, read here.

For the above reason, we cannot do something like this:

The Solution

There are a lot of viable workarounds around the web: most of them are collected in this StackOverflow threads. However, no one of the listed one was DRY enough for my tastes. For this very reason, I did some research and eventually I came up writing this simple helper method:

The above technique allows me to deal with this issue just the way I wanted to, without having to repeat a single line of code.

It can be used in the following way:

Conclusion

That's it for now: I hope that the above method will help most ASP.NET MVC developers to deal with their htmlAttributes!

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

5 Comments on “ASP.NET MVC - How to set HtmlAttributes programmatically in Razor HTML helpers A short guide explaining how to dynamically set the HtmlAttributes in Html.TextBoxFor, LabelFor and other Razor HTML helpers

  1. Hey bud, appreciate the article. I realize that this is an old article but I just wanted to note one thing. Your article uses the spelling, “dinamically” which is incorrect. The correct spelling is “Dynamically”.

    https://www.merriam-webster.com/thesaurus/dynamically

  2. Hi friend!!

    Thanks about the post!! It was very useful.

    I don’t know if you passed thru what I passed.

    I dont’t know if it is because the front-end I’m using ( Metro UI ), but it turns out that in my code the “select” and “input” controls behave different.

    The “select” do not accept the “readonly” while the “input” does, so, I changed you code and finish with this bellow.

    public static IDictionary<string, object> GetHtmlAttributes(this HtmlHelper helper, object fixedHtmlAttributes = null, object dynamicHtmlAttributes = null)
    {
    var rvd = (fixedHtmlAttributes == null) ? new RouteValueDictionary() : HtmlHelper.AnonymousObjectToHtmlAttributes(fixedHtmlAttributes);

    if (dynamicHtmlAttributes != null)
    {
    Type t = dynamicHtmlAttributes.GetType();

    foreach(var prop in dynamicHtmlAttributes.GetType().GetProperties())
    {
    rvd[prop.Name] = prop.GetValue(dynamicHtmlAttributes);
    }
    }
    return rvd;
    }

    I just made it as a extension to the class HtmlHelper, and changed the “dynamicHtmlAttributes” parameter to “object”.

    Now I can use like this:

    Html.TextBoxFor(m => m.Name, GetHtmlAttributes(new { @class=”someclass” }, (adding ? null : new { readonly = “readonly” })))

    Or

    Html.DropDownList(m => m.Name, GetHtmlAttributes(new { @class=”someclass” }, (adding ? null : new { disabled= “disabled” })))

  3. if (condition)
    {
    @Html.CheckBox(“chk”, (bool)check, new { })
    }
    else
    {
    @Html.CheckBox(“chk”, (bool)check, new { readonly = “readonly” })

                                        }
    

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.