Load user controls from an HttpHandler in ASP.NET

by Mads Kristensen 17. September 2007 23:29

Today I had what seemed to be an easy task of serving the rendered HTML of a user control through an Httphandler (.ashx). It’s something I’ve done many times before but never from an HttpHandler. If you want to do it from an .aspx page it is very easy. You just reference the user control and then the code-behind can access it in a strongly typed way when calling LoadControl("control.ascx").

An HttpHandler however does not have a LoadControl method and it doesn’t have a way of referencing user controls like a page does. What started as an easy task now turned into something unknown – reflection was needed.

The code

So, this is the method I came up with using reflection.

System.Web.UI.Page page = new System.Web.UI.Page(); 
UserControl profile = (UserControl)page.LoadControl("~/controls/profile.ascx");

Type type = profile.GetType();
type.GetProperty("Name").SetValue(profile, "John Smith", null);
type.GetProperty("Age").SetValue(profile, 53, null);

Notice that I use a fully qualified relative path to load the profile.ascx control. That is because if you pre-compile the web application it would fail otherwise. I don’t know if it’s a bug or not, but this is the way around it.

I don’t think the solution is very pretty, but it’s not ugly either. It’s short and precise and the reflection part is very transparent. No matter what, it solved the problem of loading user controls from an HttpHandler.

* Only $4.95/month ASP.NET & Windows 2008 + IIS 7 Hosting! FREE SQL Included

Tags: ,

ASP.NET

Comments

9/18/2007 3:03:46 AM #

Dan

I did a similar thing in the past, the unique problem I remember was the server controls and the javascript generated ( _doPostback() and so on ).
But I suppose that if you load a UserControl from an IHttpHandler different from the normal one you don't care about server controls, only about plain html.

And another thing, if you put an .ascx file at App_Code folder the user control is compiled and you can create it with Page.LoadControl( typeof( MyUserControl ),null)

Dan |

9/20/2007 7:48:41 PM #

Marc

Hm, I dont get it working, my Page_Load event in my ascx control is never fired?

Marc |

9/20/2007 8:34:01 PM #

Mads Kristensen

Instead of Page_Load, override the OnLoad() method instead.

Mads Kristensen Denmark |

9/20/2007 9:06:59 PM #

Marc

well, I have


public partial class WebUserControl : System.Web.UI.UserControl
{
  protected override void OnLoad(EventArgs e)
  {
    base.OnLoad(e);

    List<CartItem> cart = Cart.GetCart();

    foreach (CartItem c in cart)
    {
      BulletedList1.Items.Add(new ListItem("ID=" + c.ID + " count=" + c.Count));
    }
  }
}


<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>
<div>

  <asp:BulletedList ID="BulletedList1" runat="server">
  </asp:BulletedList>

</div>


But I always get TargetInvocationException.

Marc |

9/20/2007 9:13:45 PM #

Marc

Maybe it is something different, I try to use this code in an AJAX library to return html rendered string back. the AJAX library can return HtmlControls and maybe UserControls. the lib is ajaxpro.info.

Marc |

9/22/2007 1:04:48 AM #

kingbin

You could also just cast your control back to the original type and then set it like so:

System.Web.UI.Page page = new System.Web.UI.Page();
Control ctrl = page.LoadControl("~/controls/profile.ascx");

((Profile)ctrl).Name = "John Smith";
((Profile)ctrl).Age = 53;

page.Controls.Add( ctrl );

I think that would be a little more efficient in running since you don't have to use the getproperty and setvalue calls. This should give you the same affect you're wanting...

kingbin United States |

9/22/2007 5:31:25 PM #

Mads Kristensen

@Kingbin. That will only work if you are using the WAP model. The whole issue is that from an HttpHandler you cannot get access Profile type in a website project model. It is as though it doesn't exist.

Mads Kristensen Denmark |

9/24/2007 6:17:57 AM #

pingback

Pingback from rtipton.wordpress.com

Weekly Link Post 8 « Rhonda Tipton’s WebLog

rtipton.wordpress.com |

3/17/2009 12:42:26 AM #

Erhan Hosca

you could also do :

        UserControl ctl = new UserControl();
        ctl.LoadControl("~/controls/profile.ascx");

Erhan Hosca United States |

Comments are closed

About the slave

Mads Kristensen Mads Kristensen
Web developer at ZYB and founder of BlogEngine.NET. More...

LinkedIn ZYB Facebook Last.fm Twitter View Mads Kristensen's profile on Technorati

The Lounge

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008