Coding Tips & Tricks


Home>ASMX

Rendering a Usercontrol as a String for Webservices

I am currently working a project at work that requires us to use progressive enhancement so that our site is accessible to all users regardless of whether they have javascript enabled. One of the issues that we came across was keeping only one version of the html that we needed to use, regardless whether we were rendering our HTML client side or server side.

That way, we only ever had one version of the HTML and this also allowed us to use the same usercontrol server side. This also makes it easier for us to maintain the code.We decided to use usercontrols and just render them as a string to the client side, it is a sneaky approach but it seems to be working nicely.

Spanner

In order to render your user control as a string, simply do the following.

public string RenderViewDdl(string path, List<string> data)
{

     Page
pageHolder = new Page();
     ctlUserControl viewControl = (ctlUserControl)pageHolder.LoadControl(path);
     viewControl.Data = data;
     pageHolder.Controls.Add(viewControl);
     StringWriter output = new StringWriter();
     HttpContext.Current.Server.Execute(pageHolder, output, false);

    return output.ToString();
}

There is also a public variable on the usercontrol that allows you to set the data to display using these lines.

    public partial class ctlUserControl : System.Web.UI.UserControl

    {

        public List<string> Data;

       

        protected void Page_Load(object sender, EventArgs e)

        {

            ddlItems.DataSource = Data;

            ddlItems.DataBind();

        }

    }

While working on this, one of my colleagues (Mr. Robin Osborne - thanks Robin!), came across an error while trying to render a usercontrol with an asp.net server side control (For example a drop down list).

This is the following error he received:

System.Web.HttpException: Error executing child request for handler System.Web.UI.Page'. ---> System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.HttpException: Control 'ctl00_ddlCities' of type 'DropDownList' must be placed inside a form tag with runat=server.

1. In order to solve this problem, generate a new “page” class that inherits System.Web.UI.Page and overrides VerifyRenderingInServerForm to do nothing:

public class PageOverride : System.Web.UI.Page
{
   public override void VerifyRenderingInServerForm(System.Web.UI.Control control)
  {
   }
}

2. When creating your Page holder, use the new page (PageOverride) instead of Page in your rendering:

Page pageHolder = new ctlUserControl.PageOverride();

This is sneaky and it works like a charm! I've included a small project that show this in action.

Download Download

Further reading
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

http://stevesmithblog.com/blog/render-control-as-string/

http://jamesewelch.wordpress.com/2008/07/11/how-to-render-a-aspnet-user-control-within-a-web-service-and-return-the-generated-html/

http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx

http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/








Comments

Lee Dumond - 3/9/2010
Also would recommend the following to add to your "further reading" list: http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/

Dean Hume - 3/9/2010
@Lee - Thanks for that, Ive added it to the list.

Rasheed - 9/2/2010
Nice article. It helped me. Thanks

Peterga - 4/13/2011
Nice article. But what about user controls that need server side events, javascripts and viewstate?

Vikas Mehta - 8/13/2012
The above solution works perfectly for us in ASP.Net 3.5 (Website compiled in VS 2008). It gives us below exception when we migrated to ASP.Net 4.0 targeting framework 4.0 Error Details: Error executing child request for handler 'PageOverride'. Your help is appreciated.

anil - 10/31/2013
Hi above solution was not working .net 4.0 framework. getting the error "executing child request for handler 'PageOverride' .


Add your comment

300 Characters left


Please fill this in to confirm that you are human