Categories
Uncategorized

Ajax with ASP.Net User Controls

The Project

I have this present project which is a migrate of a wizard from ColdFusion to ASP.Net. Sounds simple. Think again!

Well one of the major components is the AJAX calendar control. The calendar uses AJAX because, well I suppose because the original author didn’t put in the logic as the calendar was dependant upon the site and there were two calendars. I won’t get into the reasons behind that but that’s what was there.

So here I am need to migrate that to ASP.Net. I had two choices I could embed the calendar logic into some javascript, or I could just convert the ColdFusion code over to ASP.Net. I chose the latter.

This seems simple enough, make a user control, embed on page, override the DataBind() method and Bob’s your uncle. Well uh no, because this was an AJAX control yeah? So I would need to fetch the appropriate month over AJAX and plop it into the DOM in correct place (well ask jQuery to do that!).

So how do we render a UserControl out to a string so it can be returned via JSON and rendered? I’ll show you.

The Solution

So I’ll assume you know how to create a User Control and you have one ready. There is nothing special you have to do, your PageLoad() etc. can be the same as you would normally do.

But now we get on to the crux. We create a Webservice entry point – which will be invoked by the calendar jQuery. It could look something like:


<WebMethod()> _
 <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
 Public Function reloadCalendar(sSiteID As String, nSiteNumber As String, calmonth As String) As String

...
End Function

Now what we need to do is create a page holder for the user control. Put the control on the page. Set its attributes and then render the page.


' need to create a fake page. put the control on it and then render. see how that goes
 Dim httpreqst As HttpRequest = HttpContext.Current.Request
 Dim httprespnse As HttpResponse = HttpContext.Current.Response

Dim pageHolder As FormlessPage = New FormlessPage
 Dim ctrl As reportwizardcalendar = CType(pageHolder.LoadControl("~/UserControls/reportwizardcalendar.ascx"), reportwizardcalendar)

ctrl.ID = "Calendar"

pageHolder.Controls.Add(ctrl)

This create a new page based on our class Formless Page defined below. Loads the control, set’s it’s ID and then add it to the page. Note that the ID here MUST be same as what the User Control ID is defined on the page which you are using this User Control on. Especially true if you have javascript tied to it.


Public Class FormlessPage
 Inherits Page

Public Overrides Sub VerifyRenderingInServerForm(control As Control)
 End Sub

End Class

This class disables the control check which forces some controls to be on a form. We don’t want to render a form element (we already have one!) so this is necessary.

Then render out the control to a string and return as the JSON


Dim sText As New StringWriter
 Dim sOutput As New HtmlTextWriter(sText)
 HttpContext.Current.Server.Execute(pageHolder, sOutput, False)
 Return sText.ToString()

Which renders the page out to the string.

All together the code looks like


<WebMethod()> _
 <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
 Public Function reloadCalendar(sSiteID As String, nSiteNumber As String, calmonth As String) As String

' need to create a fake page. put the control on it and then render. see how that goes
 Dim httpreqst As HttpRequest = HttpContext.Current.Request
 Dim httprespnse As HttpResponse = HttpContext.Current.Response

Dim foo As String = httpreqst("foo")
 Dim pageHolder As FormlessPage = New FormlessPage
 Dim ctrl As reportwizardcalendar = CType(pageHolder.LoadControl("~/UserControls/reportwizardcalendar.ascx"), reportwizardcalendar)
 ctrl.ID = "Calendar"

pageHolder.Controls.Add(ctrl)

Dim sText As New StringWriter
 Dim sOutput As New HtmlTextWriter(sText)
 HttpContext.Current.Server.Execute(pageHolder, sOutput, False)
 Return sText.ToString()
 End Function

...

Public Class FormlessPage
 Inherits Page

Public Overrides Sub VerifyRenderingInServerForm(control As Control)
 End Sub

End Class

This is a nice simple solution to a problem I’m sure that occurs a lot more often than I would like!. And no need to go to custom controls or UpdatePanels, sweet.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.