Jon Kragh's Blog » Archive of 'Oct, 2009'

Rendering an ASP.net UserControl to a String

I have been converting one of my side projects from ASP.Net WebForms to ASP.Net MVC.  In order to reuse some of my existing ASP.net UserControls from WebForms in ASP.Net MVC, I tweaked a rending method found here and here.

I improved on these methods by enabling the caller of the utility function to be the one to set properties on the UserControl in a strongly typed fashion. The is no reflection or any other special interface needed on the user control.  The key was adding a callback.

Here is what it looks like to call and render the control to a string by the caller.  In this example I am rendering my GoogleMap UserControl to a string.  The last argument I am passing is an anonymous method that is called by the utility function to initialize my control.

UIUtil.RenderUserControl<GoogleMap>("~/UserControls/GoogleMap.ascx",
    uc =>
    {
        uc.CollegeToShow = CollegeToShow;
        uc.Height = Height;
        uc.Width = Width;
        uc.Mode = Mode;
    });

The helper method is as follows:

public delegate void InitializeControlDelegate<T>(T ControlToUse);

public static string RenderUserControl<T>(string ControlPath, InitializeControlDelegate<T> InitControlCallback) where T : UserControl
{
    System.Web.UI.Page pageHolder = new Page();
    T ControlToRender = (T)pageHolder.LoadControl(ControlPath);
    pageHolder.Controls.Add(ControlToRender);
    InitControlCallback.Invoke(ControlToRender);
    StringWriter result = new StringWriter();
    System.Web.HttpContext.Current.Server.Execute(pageHolder, result, false);
    return result.ToString();
}

This method uses a similar technique as to the methods linked above, but it has a callback which calls back the anonymous method that I declared in the caller.  The callback method passes back a strongly typed UserControl as the argument that we can use to set properties on the initialized UserControl.

That is all you need to make it all work.  To make things a little nicer for myself I added “RenderToString” methods on my UserControls.  If you can’t update the UserControls themselves you can just stick code like this in a helper library.

public partial class GoogleMap : System.Web.UI.UserControl
{
    public static string RenderToString(Item ItemToShow, string Height, string Width, Constants.MapMode Mode)
    {
        return UIUtil.RenderUserControl<GoogleMap>("~/UserControls/GoogleMap.ascx",
            uc =>
            {
                uc.ItemToShow = ItemToShow;
                uc.Height = Height;
                uc.Width = Width;
                uc.Mode = Mode;
            });
    }
}

Now from within my Asp.Net MVC page (or any place else), I can render my ASP.net WebForms UserControl Google Map like so:

<%=GoogleMap.RenderToString(ItemToUse, "250px", "100%", Constants.MapMode.SingleItem)%> 

Cheers,

Jon