Home > Code > ASP.NET MVC Helper – Dynamic Forms based on Model

ASP.NET MVC Helper – Dynamic Forms based on Model

September 28th, 2009

Recently, I was working with a fairly complex data model that required a simple input form. Being the lazy programmer I am, I did not feel like crunching out the HTML required to generate this form by hand. So instead, I wrote an HTML helper class to generate the form for me.


Here is the data model we are going to be working with in this example.

public class Person
    public string Name { get; set; }
    public int Age { get; set; }
    public Address Address{ get; set; }
    public Gender Gender { get; set; }

public class Address
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }

public enum Gender


The goal here is to have a View that needs only call this helper to generate the textboxes and dropdown lists used for entering data. This way we avoid manually typing all of those angle brackets. So our View will look something like…


<h2>Dynamic Form</h2>

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

<%= Html.DynamicInputs(Model, "Enter Person Information", string.Empty) %>

    <input type="submit" value="Submit" />

<% } %>


Dynamic Input Helper

The DynamicInputHelper will enumerate the data model properties and output forms elements responsible for receiving input from the user based on the data type. This is pretty simple.


public static class DynamicFormHelper
    public static string DynamicInputs<T>(this HtmlHelper helper, T obj, string heading, string prefix)
        where T : class

        // Contruct id for model binding
        if (!string.IsNullOrEmpty(prefix))
            prefix += ".";

        // Make sure we have an instance of the obj
        if (obj == null)
            obj = (T)Activator.CreateInstance(typeof(T));

        var type = obj.GetType();

        var sb = new StringBuilder().Append("<fieldset>");

        sb.AppendFormat("<legend>{0}</legend>", heading);

        foreach (var propertyInfo in type.GetProperties())
            if ((propertyInfo.PropertyType.IsValueType && !propertyInfo.PropertyType.IsEnum) || propertyInfo.PropertyType.FullName == typeof(string).FullName)
                    "<p><label for=\"{0}\">{1}:</label>" +
                    "<input type=\"text\" id=\"{0}\" name=\"{0}\" value=\"{2}\"></p>",
                    prefix + propertyInfo.Name,
                    propertyInfo.GetValue(obj, null));
            else if (propertyInfo.PropertyType.IsEnum)
                sb.AppendFormat("<p><label for=\"{0}\">{0}:</label>", propertyInfo.PropertyType.Name.SpaceCamelCase());
                    prefix + propertyInfo.PropertyType.Name.SpaceCamelCase()));


                var child = Convert.ChangeType(propertyInfo.GetValue(obj, null) ??
                    Activator.CreateInstance(propertyInfo.PropertyType), propertyInfo.PropertyType);

                    helper.DynamicInputs(child, propertyInfo.Name, prefix + propertyInfo.Name)

        return sb.ToString();

    public static string SelectFromEnum(this HtmlHelper helper, Type type, string name)
        var sb = new StringBuilder();

        sb.AppendFormat("<select id=\"{0}\" name=\"{0}\">", name);

        foreach (var e in Enum.GetNames(type))
            sb.AppendFormat("<option value=\"{0}\">{1}</option>", (int) Enum.Parse(type, e, true), e.SpaceCamelCase());


        return sb.ToString();

    public static string SpaceCamelCase(this string camelCase)
        if (camelCase == null)
            throw new ArgumentException("Null is not allowed for StringUtils.FromCamelCase");

        var sb = new StringBuilder(camelCase.Length + 10);
        bool first = true;
        char lastChar = '\0';

        foreach (char ch in camelCase)
            if (!first &&
                 (char.IsUpper(ch) ||
                   char.IsDigit(ch) && !char.IsDigit(lastChar)))
                sb.Append(' ');

            first = false;
            lastChar = ch;

        return sb.ToString(); ;

Finished Product

If all goes according to plan you should end up with a finished product that looks something like this. The coolest part about this form is that it is rendered so the Model Binder will know how to construct the object on the server when the request is received.



Update 9/30/2009: As pointed out in the comments below, check out Input Builders MvcContrib for a more complete and robust solution for your form generation needs.

  • Facebook
  • Twitter
  • Delicious
  • Reddit
  • StumbleUpon
  • Share/Save/Bookmark
Author: Categories: Code Tags:
  1. dario-g
    September 29th, 2009 at 15:35 | #1

    Looks nice but better will be with partals for templating 🙂

  2. September 29th, 2009 at 18:29 | #2

    I found something similar by Eric Hexter called Input Builders – now a part of MvcContrib as MvcContrib.UI.InputBuilders (just added to the latest build). His uses template views and partials to build the forms.

    It’s always a lot more fun to build it yourself though! 🙂

  3. October 9th, 2013 at 08:57 | #3

    Thanks for this… license?

  4. Ananth
    February 21st, 2014 at 00:46 | #4

    Hi sir

    I am getting this error..

    ‘System.Web.Mvc.HtmlHelper’ has no applicable method named ‘DynamicInputs’ but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax. d:\MVC Projects\MvcApplication40\MvcApplication40\Views\Person\Index.aspx 10 5 MvcApplication40

  5. February 21st, 2014 at 18:46 | #5

    If you have done your preliminary work, the dog should
    go down for you. There is a department on Frree and Low cost Help which can’t allow specific referrals, butt which points you in tthe right direction.
    This time frame accounts for approximately 2,000 generations of humans since the great split, during which
    time modern genetic features developed independently.

  6. John A Davis
    June 22nd, 2014 at 02:03 | #6

    Sure would like to know how to do this not with a model of the data but with a database table schema.
    For example, there are 20 columns in a table, the code generates an input form and validation for all columns. That is more real world.

  7. November 13th, 2014 at 03:09 | #7

    I have also seen people selling on ebay or elsewhere and they sell the fakes ones while advertising them as authentic pairs. Those sellers who sell real RayBan sunglasses on ebay can get away with it , because luxottica (RayBan Factory) does not know who those retailers are.
    polo t shirts
    [url=http://www.melcrook.com.au/Connections/Plesk/RGEfdg.asp]polo t shirts[/url]

  8. June 13th, 2015 at 07:12 | #8

    Thanks for every other informative site. The place else could I am getting
    that type of info written in such a perfect approach? I’ve a undertaking that I’m
    just now working on, and I have been at the look out for such information.

  9. June 23rd, 2015 at 03:53 | #9

    Hi Dear, are you truly visiting this web site regularly, if so after that you will definitely obtain pleasant knowledge.

  10. August 28th, 2015 at 11:05 | #10

    Hi there, yes this piece of writing is actually nice and I have learned lot
    of things from it about blogging. thanks.

  11. January 28th, 2016 at 08:54 | #11

    Thanks for any other magnificent post. The place else may anyone get that type of information in such an ideal approach of writing?
    I have a presentation subsequent week, and I am on the search for
    such information.

  12. February 7th, 2016 at 05:26 | #12

    Right now it sounds like BlogEngine is the best blogging platform out there right now.
    (from what I’ve read) Is that what you’re using
    on your blog?

  13. April 4th, 2016 at 03:59 | #13

    Hi there to all, the contents existing at this website are really awesome for people knowledge,
    well, keep up the nice work fellows.

  14. where to buy wartrol
    May 7th, 2016 at 23:27 | #14

    Hmm it appears like your site ate my first comment (it was very long)
    so I guess I’ll just sum it up what I wrote and say, I’m completely enjoying your blog.
    I as well am an aspiring blogger however I’m still new to everything.
    Do you have any points for newbie blog writers?
    I’d surely appreciate it.

  15. May 24th, 2016 at 00:11 | #15

    Hellⲟ all, ɦere everу one iѕ sharing thee
    knowledge, tһսs it’s fastidious too rwad tһiѕ weblog, ɑnd I used tⲟ visit thiѕ web site every day.

  16. May 25th, 2016 at 00:01 | #16

    I feel this is one of the soo much important info for me.
    And i am happy reading your article. However should observation on few basic issues, Thhe
    web site style iss perfect, the articles is in reality excellent : D.
    Just right activity, cheers

  17. June 4th, 2016 at 14:41 | #17

    Nice post. I ѡas checking constantⅼy tɦіs weblog and
    I’m inspired! Ѵery helpful іnformation ѕpecifically tһe final
    phase 🙂 I hande sucһ info а lot. I useԁ to Ьe looкing for thjis partiucular іnformation for
    a very lⲟng time. Thank yߋu аnd goߋd luck.

  18. June 7th, 2016 at 11:37 | #18

    Remarkable issues һere. I am very hapoy too see your article.
    Τhank yоu so muϲҺ and I am having a look ahead to contact ʏoս.
    Will yoս kindly drop me a е-mail?

  19. June 7th, 2016 at 18:13 | #19

    With havin so much content and articles do you ever run into any issues of plagorism or copyright infringement?
    My site has a lot of completely unique content I’ve either created myself or outsourced but it looks like a lot of it is
    popping it up all over the web without my permission. Do
    you know any solutions to help reduce content from being ripped off?

    I’d truly appreciate it.

  20. June 13th, 2016 at 21:09 | #20

    An outstanding share! I have just forwarded this onto a co-worker who had
    been doing a little homework on this. And he actually bought me lunch because I
    found it for him… lol. So allow me to reword this….
    Thanks for the meal!! But yeah, thanks for spending time to discuss this
    topic here on your internet site.

  21. July 27th, 2016 at 05:27 | #21

    You actually make it seerm sߋ easy with your presentation but I fiind thgis topic tօ bᥱ ahtually sߋmething thаt I think I wοuld never
    understand.It ѕeems tooo complicated аnd extremely broad fօr me.

    I am lօoking forward ffor your next post,
    I’lltry tօ ɡet the hang off it!

  22. September 29th, 2016 at 23:49 | #22

    Hello, іts pleasant post concеrning media print, ԝe aⅼl now media iѕ a wonderful source of

  23. February 4th, 2017 at 01:05 | #23

    Hi I am so happy I found your webpage, I really found you by mistake,
    while I was browsing on Google for something else, Regardless
    I am here now and would just like to say many thanks for
    a remarkable post and a all round exciting blog (I also
    love the theme/design), I don’t have time to go through it all at the minute but I have book-marked it and also added in your RSS feeds, so when I have time I will be back to read much more,
    Please do keep up the great jo.

  24. May 23rd, 2017 at 04:34 | #24

    I’d like to find outt more? I’d care to find out some
    additional information.

  25. June 22nd, 2017 at 20:40 | #25

    Very good info. Lucky me I recently found your blog by chance (stumbleupon).

    I’ve book marked it for later!

  26. September 5th, 2017 at 16:21 | #26

    Thanks for finally talking about >Christopher Patterson > ASP.NET MVC Helper –
    Dynamic Forms based on Model <Liked it!

  27. November 13th, 2017 at 21:24 | #27

    If you are going for finest contents like me, only visit this site all the
    time since it provides quality contents, thanks

  28. August 15th, 2018 at 05:38 | #28

    Я уверен, что эта информация касается всех посетителей …
    Добавил в закладки, так как мне очень нравится ваш онлайн ресурс !!!

  1. January 3rd, 2017 at 16:21 | #1