Tuesday, January 16, 2007

Using Web User Controls within a web service or class.

I have this Web User Control that has a simple function of displaying a customised grid and fill it with data. Since I had to email the rendered HTML I've added a static method to the Web User Control that would render itself based on some parameters. However, in Net 2.0 one cannot dynamically use the types declared in the codebehind of a user control or page inside another control or page, only types declared in App_Code. In pages this gets solved as in the link above, but what do you do when you want to use the type inside a class in App_Code or, like I needed to, in a web service (where register directives are not allowed)?

In my case, there were two solutions. One is to create a page that loads the user control and nothing else, then read its html. That solves the problems of using the code, but adds security issues. I have to either add a security mechanism to the page or allow anyone to render the UserControl. The second solution, the one that I ended up implementing, is to use reflection.

Let's recap. I have the web user control, let's call it Wuc, and I have the static method Wuc.GetHtml(int i) that I must access from a Web Service. If I write
string s=Wuc.GetHtml(i); it doesn't get to compile, returning the error "The name 'Wuc' does not exist in the current context".

So I do something like this:
UserControl uc = new UserControl();
uc = (UserControl) uc.LoadControl("~/Wuc.ascx");

and I get the object I need to get the type of. Then I should get a reference to the method I want so I try:

MethodInfo mi = uc.GetType()

which should work, but it doesn't!

Why not? Because the type of the object is not Wuc is wuc_ascx and it's the dynamically generated ASP.NET type. I get all the methods of Wuc, but not the static ones! So, the (really ugly) solution is to make the method not static and use this code:

MethodInfo mi = uc.GetType()
string s = (string)mi.Invoke(uc, new object[] { i });

which finally works.

Scott Gu was nice enough to respond to my request on how to do this. He has this blog entry that explains how to render a control in NET 2.0 within an ASP.NET Ajax environment, but what really connects with my blog entry is this archive and the ViewManager object. Scott uses here the Page.LoadControl method (here is why) to load the control and Server.Execute instead of RenderControl.


Anonymous said...

Very Useful bt u didnt define i :)