Enhancing the 'Email the Rendered Output of an ASP.NET Web Control' Code, Part 2By Scott Mitchell
In Part 1 we saw one technique for rendering the contents of a DataGrid that contains in its control hierarchy controls that require they be in a server-side form. In this final part of this article we'll look at another related approach to solve the same problem.
Creating a New
Page Instance for Rendering
Rather than rendering the server-side form defined in the ASP.NET Web page's HTML portion, we can programmatically create a new
Pageinstance with a new server-side form instance. We can then add the DataGrid (or whatever Web control we want to email the rendered contents of) to the server-side form, and then render the
Pageinstance by calling the
RenderControl()method. (This technique was thought up by Andy Smith, whose knowledge of ASP.NET control development is best shown by his numerous free ASP.NET server controls available at MetaBuilders.com.)
The code for this approach is shown below. Note that we don't need to programmatically set the
property of any controls. Rather, we just create a new
Page instance and a new server-side form, build
up the control hierarchy, add the DataGrid, and call the programmatically-created
method. We don't need any Panel controls either.
A couple things to notice here - before adding the
dgPopularFAQs DataGrid to the programmatically-created
server-side form, we needed to first remember where in the
Controls collection of
belonged. This is because after we render the contents of the programmatically-created
Page, we'll need
to place the DataGrid back in
Controls collection, and we want to place it back in
the right place.
Second, note that we call the
DesignerInitialize() method prior to calling the
RenderControl() method. This causes the
Page class's protected
method to be called, which preps a number of properties needed for rendering. (Omitting this call to
will result in an exception being thrown since it won't properly mark that the server-side form has been rendered when the DataGrid's
LinkButton is rendered...)
With this approach, we don't need to worry ourselves with hiding the
myForm server-side form since it is
only rendered once the entire page life-cycle.
Creating a Base Page Class That Overrides the
The crux of the problem the two workarounds examined earlier in this article attempt to overcome is that the
VerifyRenderingInServerForm()method throws an exception if the control being rendered is not located within a Web Form. Rather than trying to "fake out" the existing
VerifyRenderingInServerForm()method (which is what the two previous workarounds do), we could just create our own base
Pageclass and override the
Page class is a class that extends the built-in
System.Web.UI.Page, but adds to or customizes
its functionality. Once this base
Page class has been created, we can have our ASP.NET pages derive from it instead
System.Web.UI.Page. For more on this technique, be sure to read Using a Custom Base Class
for your ASP.NET Page's Code-Behind Classes.
Start by creating a class in your project named
EmailReadyPage and use the following code:
This class derives from
System.Web.UI.Page and overrides its
that it does nothing. That is, with the code above, when
VerifyRenderingInServerForm() no exception is thrown,
regardless of whether the control appears within a Web Form.
Finally, configure your ASP.NET page(s) that send emails of rendered control markup to use the
class as its base class by replacing the
Inherits System.Web.UI.Page in the ASP.NET code-behind class with
In this article we saw how to improve the code from Emailing the Rendered Output of an ASP.NET Web Control to allow for DataGrid's with LinkButtons or Buttons in their control hierarchy to be emailed as well. This feat can be accomplished in a number of ways: either by rendering the server-side form as opposed to the DataGrid, or by creating a new
Pageand server-side form, and rendering those. For a much more in-depth look at ASP.NET server control building, be sure to consider picking up a copy of Developing Microsoft ASP.NET Server Controls and Components.
|A Follow-Up Article is Available!|
|If you try out the code discussed in this article in an ASP.NET 2.0 application, you may wind up with an exception that reads: "RegisterForEventValidation can only be called during Render();" If so, check out Emailing the Rendered Output of an ASP.NET Web Control in ASP.NET 2.0 for a discussion on why this error arises along with a couple of workarounds.|