65.9K
CodeProject is changing. Read more.
Home

RenderControl doesn't work for GridView

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.07/5 (5 votes)

Nov 1, 2007

CPOL

2 min read

viewsIcon

74785

The RenderConrol method of DataGrid doesn't seem to work for GridView. Using the RenderControl method of the DataGrid to render HTML content throws an HTTPException.

Introduction

When you try to use the RenderConrol method of ASP.NET 1.1 DataGrid, it doesn't seem to work for GridView. Using RenderControl method of DataGrid to render HTML content throws an HTTPException: "System.Web.HttpException: Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server", which is already inside the form with runat=server.

Background

In most of the cases, we need to process HTML content of a DataGrid rendered like Export to Excel and using AJAX to bind the grid. So we try to use the RenderControl method of the DataGrid to get the HTML content and write it to the output stream.

The above case works fine when we the rendered grid has no controls in it. I.e,, when it is simply loaded with bound columns and no template columns.

Microsoft has accepted it as bug in .NET 1.1, and you can see it here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=118285.

I have posted a workaround below.

Using the Code

Every ASPX page has an HTML Form control with runat=server and all the controls placed inside the form tag. The concept is to add the DataGrid control to the form manually in the code-behind which is already added to the form. You can verify this by using:

//"Form1" - HTMLForm id and "GridView1" - Grid id
Form1.FindControl("GridView1");

Before using the above code, you have to declare the form instance as.

protected System.Web.UI.HtmlControls.HtmlForm Form1; //(Form1 - Form id)

The above code returns the GridView control, which means it is already inside a form with runat= server. But if you try to use the RenderControl method of the GridView as below:

System.Text.StringBuilder sb = new System.Text.StringBuilder();
HtmlTextWriter htWriter = new HtmlTextWriter(new System.IO.StringWriter(sb));
GridView1.RenderControl(htWriter);

You will get this exception:

Error message: Control 'GridView1' of type 'GridView' 
               must be placed inside a form tag with runat=server.
Description: An unhandled exception occurred during the execution 
             of the current web request. Please review the stack trace for more 
             information about the error and where it originated in the code. 
Exception Details: System.Web.HttpException: Control 'GridView1' of type 
                   'GridView' must be placed inside a form tag with runat=server.

To fix this issue, use the code below which adds the GridView control to the form and uses the RenderControl method of the form instead of that of the grid. This would include "<form>" tags to the HTMLWriter. The next step is to remove unwanted tags which are added when calling the RenderControl method of the form.

Form1.Controls.Clear(); 
Form1.Controls.Add(GridView1); 
System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
HtmlTextWriter htWriter = 
    new HtmlTextWriter(new System.IO.StringWriter(sb)); 
Form1.RenderControl(htWriter); 

string strRenderedHTML = sb.ToString(); 
int startindex = strRenderedHTML .IndexOf("<table"); 
int endindex = strRenderedHTML .IndexOf("</table>"); 
int length = (endindex-startindex)+8; 
strRenderedHTML = strRenderedHTML .Substring(startindex,length);

Use the above code to remove "<form>" and viewstate "<input>" tags that get rendered with the grid HTML content. You would get the exact HTML content that GridView renders.

Points of Interest

The interesting thing about this issue is that I tried to find a workaround to fix this issue in the internet, but in vain. Another important factor is that the form instance has to be manually declared like:

protected System.Web.UI.HtmlControls.HtmlForm Form1;
//(Form1 - Form id)

History

No history yet.