Home > Programming > Using Web Forms user controls in an ASP.NET MVC project

Using Web Forms user controls in an ASP.NET MVC project

We have an existing ASP.NET Web Forms project that we’re in the process of slowly converting to ASP.NET MVC. We do not have the manpower to simply rewrite the entire website from scratch, so one of our goals is to slowly convert the website piece by piece. This means that the existing Web Forms project will need to coexist with emerging MVC project.

In the current Web Forms project, we have a number of user controls that are used on all our pages. In order to maintain backwards compatibility with our Web Forms pages, we couldn’t rewrite the controls as MVC helpers without having to duplicate code.

I created this helper that allows us to reuse Web Forms user controls on views:

public static class UserControlHelper
{
    public static HtmlString RenderControl<T>(this HtmlHelper helper, string path)
        where T : UserControl
    {
        return RenderControl<T>(helper, path, null);
    }
 
    public static HtmlString RenderControl<T>(this HtmlHelper helper, string path, Action<T> action)
        where T : UserControl
    {
        Page page = new Page();
        T control = (T)page.LoadControl(path);
        page.Controls.Add(control);
 
        if (action != null)
            action(control);
 
        using (StringWriter sw = new StringWriter())
        {
            HttpContext.Current.Server.Execute(page, sw, false);               
            return new HtmlString(sw.ToString());
        }
    }
}

By instantiating a Page and adding the user control to it, we can render the result as a string. To use the helper on a view, we can call it like this:

@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx"))

The entire method call needs to be surrounded with parentheses, otherwise the angle brackets will confuse the Razor view engine. If the user control has properties that need to be set, we can call the method overload and pass it an expression:

@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx", x => x.Name = "Malvin"))
 
@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx", x =>
    {
        x.Name = "Malvin";
        x.Age = 25;
    }))
  1. Kiran
    June 30, 2011 at 1:34 pm | #1

    This seem to be working only if the User Contorl as read-only data. If there are any buttons and if there are any server events on the button clicks, the events are not getting fired. Probably, the event wiring with server controls is missing. Is there a way to solve this issue quickly?

    • Raj
      August 30, 2011 at 9:32 pm | #2

      I am also interested if there is a solution for wiring up the events of asp.net usercontrols?

    • RazorBlade
      December 30, 2012 at 4:47 pm | #3

      RE: This seems to be working only if the User Contrl as read-only data…
      Indeed the approach seems appealing at first sight… but to good to be true? I’m afraid it ends right there as far as options… the control will be rendered in read-only . So if you try to create, let’s say an ascx control
      which contains an asp:GridView binded to a database query, the result will be displayed all right in the gridview, but I’m afraid you won’t be able to do anything else afterwards, like clicking on checkbox in a cell, not even adding sorting, nor paging… it seems pretty much static at this stage… too bad…

  2. Dave
    September 8, 2011 at 4:30 pm | #4

    Yes, I am interested in using this on controls that do not just render read only data. Thanks

  3. Thiago Passos
    December 20, 2012 at 5:38 am | #5

    Awesome man! Exactly what I needed. migrating old projects to MVC has been easy after this html helper. Cheers!

  4. Glocken
    July 20, 2013 at 9:17 am | #6

    I’m interested in reusing my ascx controls as well. and I’ve searched a lot but there is no solution that can make ascx fully reusable in mvc (that doesn’t make sense though, I just want it for migrating proposes). It seems that the only approach for doing that is to make user controls, postback free. after that may be we can use this helper to load them.
    any idea to eliminate postbacks?

  5. Srilaxmi
    February 3, 2014 at 2:37 am | #7

    It seems good , but button events are not fired and hidden field values are not getting , please help me its very urgent

  6. Srilaxmi
    February 3, 2014 at 2:44 am | #8

    Srilaxmi :
    It seems good , but button events are not fired and hidden field values are not getting in usercontrol, please help me its very urgent

  1. No trackbacks yet.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: