The product of a web developer with a little too much caffeine

WebForms And MVC In Harmony — Almost…

with 6 comments

Check out a new post about using WebControls inline with MVC that actually works with postbacks!

Pop Quiz – What happens with the following snippet of ASP.NET code?

<% int number = 5; %>
<asp:PlaceHolder runat="server" >
<% =number %>    

Prints the number 5? Nope. Maybe it equals zero? Sorta. How about this…

Compiler Error Message: CS0103: The name ‘number’ does not exist in the current context


I’ve complained before about the disconnect between WebControls and actual inline code. WebControls are still a very convenient way to write templates but because they exist in a different context than inline code they are effectively off limits. As cool as MVC is you’re pretty much stuck throwing all your existing WebControls out the window. Or are you?

Using Extension Methods Instead of Controls

Extension Methods came in really at the best time possible. I can’t see MVC working without them.

If you’ve never used one before, an Extension Method lets you create a static method else where in your project, do a couple fancy assignments and then it attaches that method onto the class you’re targeting. LINQ heavily relies on Extension Methods to provide such a seamless programming experience.

One way that ASP.NET MVC uses Extension Methods is to make working with certain control types easier. For example there is a method to create the input tag, one to render a form tag, etc…

Below is an example of how you could create an Extension Method that is attached to the HtmlHelper.

public static class MyExtensionMethods {

    //example method - don't write things this ugly
    public static string BulletList(this HtmlHelper helper, params string[] items) {
        return string.Concat(
            string.Join("</li><li>", items),

In our example we create a static class to house our Extension Methods. We also create static methods with a strange argument at the start. This argument is actually the class were attaching the method to. Now we can use our code like so…

<% =this.Html.BulletList("Apple", "Orange", "Pear") %>

Cool. If you’re not familiar on the things you can do with Extension Methods then I recommend you read about them some more before you start trying to add them to your project. You could also use delegates to simulate templating within an Extension Method.

public static class MyExtensionMethods {

    //example method - renders the content of each action
    public static void TwoColumns(this HtmlHelper helper, Action left, Action right) {
        HttpContext.Current.Response.Write("<div class='left'>");
        HttpContext.Current.Response.Write("<div class='right'>");

Then you can use your “template” like so…

<% this.Html.TwoColumns(() => { /* Left Column */ %>
    I'm on the left!
<% }, () => { /* Right Column */ %>
    I'm on the right!
<% }); /* End Two Column */ %>

Code like this can get ugly in a hurry – so be conservative in your use.

Using IDisposable To Close Tags

Another way you can create a “WebControl” with ASP.NET MVC is to create a class that implements IDisposable. By placing markup in the constructor and the Dispose method you can essentially write your RenderBeginTag() and RenderEndTag() methods you normally find on CompositeControls!

public class StyledHeader : IDisposable {

    public StyledHeader(string color) {
        HttpContext.Current.Response.Write("<h1 style='color:" + color + "' >");

    public void Dispose() {

Naturally, StyledHeader should have been added to the core of the ASP.NET MVC library, but somehow it got missed :). In any case, our class can be used with the using keyword to render our fancy new header.

<% using (new StyledHeader("#f00")) { %>
    Howdy - This is my header control!
<% } /* End StyledHeader */ %>

The Super Secret Final Method

As you noticed at the beginning of my post I mentioned about throwing away WebControls since they aren’t any use to us anymore. Well, that isn’t true — We can still use WebControl with our inline code for the page!

If you’ve read any of my previous blog posts, you can see that I’m a big fan of overriding the Render() method for WebControls. In similar fashion, we’re going to use the RenderControl() method to render our WebControls right when we need them.

using System.Reflection;
using System.IO;
using System.Web.UI;
using System.Web;
using System.Web.Mvc;

public static class MyExtensionMethods {

    //example method - renders a webcontrol to the page
    public static void RenderControl(this HtmlHelper helper, Control control) {

        //perform databinding if needed
        //MethodInfo bind = control.GetType().GetMethod("DataBind");
        //if (bind is System.Reflection.MethodInfo) {
        //    bind.Invoke(control, null);

        //Call a courtesy databind
        //Thanks for pointing it out Richard
        //render the HTML for this control
        StringWriter writer = new StringWriter();
        HtmlTextWriter html = new HtmlTextWriter(writer);       

        //write the output 
        //and cleanup the writers


You may notice the courtesy DataBind() call we’re doing there — Just in case something has a DataSource I was calling the method as well. Depending on how you use this you may want to change this some. But enough of that, how is it used?

<% int[] numbers = { 1, 2, 3, 4, 5 }; %>
<% this.Html.RenderControl(new DataGrid() { DataSource = numbers }); %>

You can also define your class before you pass it into the RenderControl method in case you need to do a little more to it than just assign some values to the properties.

Finally, WebForms and MVC In Harmony… Or Maybe Not…

Now I won’t pretend that you can plug all of your WebControls into this and expect it to work like WebForms used to. A lot of things are missing that a lot of WebControls rely on (like the ViewState). But, if your mainly interested in the rendered output of a WebControl then you’re in luck.

Written by hugoware

June 18, 2009 at 2:11 am

6 Responses

Subscribe to comments with RSS.

  1. WebForms And MVC In Harmony — Almost… « Yet Another WebDev Blog…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…


    June 18, 2009 at 9:44 am

  2. […] to VoteWebForms And MVC In Harmony — Almost… (6/17/2009)Wednesday, June 17, 2009 from webdev_hbPop Quiz – What happens with the following snippet of […]

  3. Why are you using reflection to call the DataBind method? It’s much easier, not to mention more efficient, to replace:

    MethodInfo bind = control.GetType().GetMethod(“DataBind”);
    if (bind is System.Reflection.MethodInfo) {
    bind.Invoke(control, null);




    July 14, 2009 at 10:49 am

    • Actually, you’re correct – I had intended that to allow any type of control to be passed in, even those that do not support data-binding.

      I’m not sure what I was thinking when I put this together, but DataBind is a method of Control, not any inherited classes. Your suggestion would, in fact, be much better.

      Thanks for the feedback.


      July 14, 2009 at 11:12 am

  4. […] blogged awhile back about using WebControls inside an MVC application, but it covered only controls that didn’t need to postback to the server. Not really that […]

  5. […] instead of an actual UserControl. Its not that you can’t use them but that there is a disconnect between the control state and the render phase which makes it pretty much impossible to really work with them […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

%d bloggers like this: