Sunday, October 2, 2011

Asp.net Mvc Control, replacement for Asp.net Server control

This tutorial is dedicated to all the newbie who just started out with Asp.net MVC and have been wondering why all those mighty(and bulky) asp.net server controls have been suddenly discarded by Asp.net MVC team. You might also be wondering why do MVC pros don’t recommend you to use asp.net server controls, and if so is it fair to have all those boiler plate codes scattered all over your pages which in case of Asp.net server controls, minimized a lot with just few properties to tweak.

Well the fact is Asp.net server controls have not vanished away from Asp.net MVC. It’s just it really doesn’t fit and suit well with MVC. Having an Asp.net Server control on your MVC view is like having to see a 60 year old man mingling with a hot girl of your dream. However it might blend sometime, totally depending on the various situations. To tell you the truth I’ve done that too.

Well let’s get back to why…..? Its coz Asp.net server controls are very tightly coupled with page lifecycle and maintaining the states between user requests. To do so it emits all those heavy and dirty viewstate strings to the user and does all the dirty work of re-parsing those view state to reinstate the control on postback. Web is actually stateless architecture. And it is why web is much favored much by many and in many cases. Working so hard to maintain the control state doesn’t seem right. And that is where ajax comes in play.

So what do we do to minimize the code for some portion of your application which might be repeated over and over again in your views. Asp.net server controls did all the dirty jobs of emitting necessary scripts and html elements. All you had to do was to change few properties. Well I guess you already have the answer for this. Yes, the Html Helper. But not really , Html Helper comes to the rescue but doesn’t do much than to help you with some contextual data and render an Html string. You must have already seen a way to render a textbox using Html.TextBox() or a checkbox. Well the TextBox extension method of HtmlHelper actually takes a few parameters and based on that parameter returns the final string or a MVCHtmlString.
Let’s get back to the real thing building a small html helper extension which is responsible to build a table with supplied number of columns and rows and table headers.

All this starts with creating a static extension class.

Here I’d like to name the class as TableBuilderExtension
The class looks something like this.
using System.Web.Mvc;
 namespace MyApp.Helpers

public static class TableBuilderExtension
    {

        
    }

Now let’s create an extension method named Table which takes a tableName,numberOfColumns, numberOfRows and headers as parameters and build the table with headers based on these supplied parameter

public static System.Web.Mvc.MvcHtmlString Table(this HtmlHelper helper, string tableName, int numberOfColumns, int numberOfRows,string[] headers)
        {
            TagBuilder builder = new TagBuilder("table");
            builder.GenerateId(tableName);
            
for (int i = 0; i < numberOfRows; i++)
            {
                TagBuilder rowBuilder = new TagBuilder("tr");

                for (int j = 0; j < numberOfColumns; j++)
                {
                    TagBuilder cellBuilder = new TagBuilder("td");
                    if (i == 0)
                    {
                        cellBuilder = new TagBuilder("th");
                        cellBuilder.InnerHtml = headers[j];
                    }
                    else
                    {
                        cellBuilder.InnerHtml = " ";
                    }
                    
                    rowBuilder.InnerHtml += cellBuilder.ToString();
                }

                builder.InnerHtml += rowBuilder.ToString();
            }

            return new MvcHtmlString(builder.ToString());
            //or
            //return builder.ToString(); //for this change the return type to a simple string type.


        }
Remember the first parameter in the function. This makes your function an extension method for the type HtmlHelper class. And this is what extends the htmlhelper class and appends your function to the class(provided the namespace is imported wherever you are using this htmlhelper class). The code is really really simple. Here I’ve used a TagBuilder class to build an html element which simplifies our work. It also provides various other functions such as AddCssClass, MergeAttributes to add a css class and extra attributes to your html tag. And Finally note the MvcHtmlString return type which is nothing more than a HtmlString type and returns the html string on ToString() function. You can also replace the return type as a simple string and simply return a string instead. You also have your htmlhelper which provides you all the contextual data required related to your view. You can use them in various ways depending on the type of control you are building. There you have it…. It’s a piece of cake. You can simply use this in you view as
@Html.Table("mytable", 3, 10,new string[]{"Header 1","Header 2","Header 3"})

If you want to explore more you can simply download the Asp.net MVC project from codeplex. It’s open source, so no charges and take a look at various htmlhelper extension methods such as TextBox, CheckBox and see how the htmlhelper object can be very helpful in generating the id and name of for your input elements and model errors, model values and blah blah blah…

Thank you all for reading this post.