Load user controls from an HttpHandler in ASP.NET

Sep 17, 2007

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.

* $4.95/month BlogEngine.net Hosting – Click Here!

Comments (8) -

Dan
Dan
9/17/2007 6:03:46 PM #

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)

Marc
Marc
9/20/2007 10:48:41 AM #

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

Mads Kristensen
Mads Kristensen Denmark
9/20/2007 11:34:01 AM #

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

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

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
Marc
9/20/2007 12:13:45 PM #

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.

kingbin
kingbin United States
9/21/2007 4:04:48 PM #

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...

Mads Kristensen
Mads Kristensen Denmark
9/22/2007 8:31:25 AM #

@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.

Erhan Hosca
Erhan Hosca United States
3/16/2009 3:42:26 PM #

you could also do :

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

Pingbacks and trackbacks (1)+

Comments are closed

About the author

Mads Kristensen

Mads Kristensen
Program Manager at the Microsoft Web Platform team and founder of BlogEngine.NET.

More...

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.