获取控件生成的html
时间:2011-05-12 来源:lorgine
在很多时候,我们需要直接获取到GridView等服务器控件生成的HTML代码,例如导出Excel,或者使用Ajax进行局部刷新时。
假若你使用Ajax Pro要局部更新一个GridView,可以尝试直接返回GridView生成的Html代码。
Asp.net的服务器控件,都有一个RenderControl方法,使用控件的这个方法,我们可以很方便的得到该控件生成的Html代码,但现实和想角往往是有差距的。在我得到GridView的过程中遇到了两个问题。
得到GridView生成的Html Code:
- /// <summary>
- /// 用来做例子中的数据源
- /// </summary>
- /// <returns></returns>
- private DataTable BuildGridViewDataSource()
- {
- DataTable dt = new DataTable();
- dt.Columns.Add("Number");
- DataRow dr = dt.NewRow();
- dr["Number"] = "1000";
- dt.Rows.Add(dr);
- dr = dt.NewRow();
- dr["Number"] = "1001";
- dt.Rows.Add(dr);
- return dt;
- }
- public void BindGridView()
- {
- GridView1.DataSource = BuildGridViewDataSource();
- GridView1.DataBind();
- }
- BindGridView();
- StringWriter tw = new StringWriter();
- HtmlTextWriter writer = new HtmlTextWriter(tw);
- GridView1.RenderControl(writer);
- DIV_Test.InnerHtml = writer.InnerWriter.ToString(); //writer.InnerWriter即是我们需要的GridView Html代码
问题1:类型“GridView”的控件“GridView1”必须放在具有 runat=server 的窗体标记内。
解决了问题1后,又遇到了
问题2:只能在执行 Render() 的过程中调用 RegisterForEventValidation
第一个问题通过查询MSDN文档库,发现如下描述:
如果控件未在移动 Web 窗体中以 DesignMode 呈现,则此方法将重写 Page.VerifyRenderingInServerForm 方法以引发异常。
必须位于 <form runat=server> 标记中的控件可以在呈现之前调用此方法,以便在控件被置于标记外时显示错误信息。发送回或依赖于注册的脚本块的控件应该在 Control.Render 方法的重写中调用此方法。呈现服务器窗体元素的方式不同的页可以重写此方法以在不同的条件下引发异常。
如果回发或使用客户端脚本的服务器控件没有包含在 HtmlForm 服务器控件 (<form runat="server">) 标记中,它们将无法正常工作。这些控件可以在呈现时调用该方法,以在它们没有包含在 HtmlForm 控件中时提供明确的错误信息。
开发自定义服务器控件时,通常在为任何类型的输入标记重写 Render 方法时调用该方法。这在输入控件调用 GetPostBackEventReference 或发出客户端脚本时尤其重要。复合服务器控件不需要作出此调用。
简单来说,这个方法就是验证控件是否是在<form runat="server">标记中,注意上面加粗的文字,那么我们找到了解决办法,最简直就是复写 VerifyRenderingInServerForm这个方法,让他不验证,这关就过了,为了不影响其实应用,所以我们可以对Control的 Type进行验证,只有当Control是GridView或者其它会引发这个异常的Control,我们跳过验证。
- public override void VerifyRenderingInServerForm(Control control)
- {
- //如果control是GridView,跳过验证,这里最好的验证是验证control的Id
- if (control is GridView || control is RadioButton)
- {
- return;
- }
- base.VerifyRenderingInServerForm(control);
- }
问题2的解决办法,在MSDN库中查到RegisterForEventValidation的作用为验证注册事件引用。 在Page的Html页首加入EnableEventValidation="false",跳过这个验证,这样问题2解决。
- <%@ Page Language="C#" AutoEventWireup="true" EnableEventValidation="true" CodeFile="TestRenderControl.aspx.cs" Inherits="TestRenderControl" %>
下面提供一个得到UserControl 的Html代码的完整例子,它和得到GridView的Html代码是一样的。
UserControl Code:
ASCX
- <%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>
- <asp:GridView ID="GridView1" runat="server">
- <Columns>
- <asp:TemplateField HeaderText="操作">
- <HeaderTemplate>
- </HeaderTemplate>
- <ItemTemplate>
- <asp:RadioButton ID="RadioButton1" runat="server" Text="选择" />
- </ItemTemplate>
- </asp:TemplateField>
- </Columns>
- </asp:GridView>
- <br />
- <asp:TextBox ID="TextBox1" runat="server">aaaaa</asp:TextBox>
- <asp:ImageButton ID="ImageButton1" runat="server" />
- <asp:DropDownList ID="DropDownList1" runat="server">
- <asp:ListItem>sdfsdfsdf</asp:ListItem>
- <asp:ListItem>dfgfdgfdg</asp:ListItem>
- <asp:ListItem></asp:ListItem>
- </asp:DropDownList>
CS Code
- using System.Data;
- using System.Configuration;
- using System.Collections;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Web.UI.HtmlControls;
- public partial class WebUserControl : System.Web.UI.UserControl
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- }
- /// <summary>
- /// 用来做例子中的数据源
- /// </summary>
- /// <returns></returns>
- private DataTable BuildGridViewDataSource()
- {
- DataTable dt = new DataTable();
- dt.Columns.Add("Number");
- DataRow dr = dt.NewRow();
- dr["Number"] = "1000";
- dt.Rows.Add(dr);
- dr = dt.NewRow();
- dr["Number"] = "1001";
- dt.Rows.Add(dr);
- return dt;
- }
- public void BindGridView()
- {
- GridView1.DataSource = BuildGridViewDataSource();
- GridView1.DataBind();
- }
- }
Test Page Html Code
- <%@ Page Language="C#" AutoEventWireup="true" EnableEventValidation="false" CodeFile="TestRenderControl.aspx.cs" Inherits="TestRenderControl" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head runat="server">
- <title>无标题页</title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div runat="server" id="DIV_Test" style="width:100%; text-align:center;"></div>
- <asp:Button ID="Submit" runat="server" Text="提交" OnClick="Submit_Click" />
- </form>
- </body>
- </html>
Test Page Cs Code
- using System;
- using System.Data;
- using System.Configuration;
- using System.Collections;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Web.UI.HtmlControls;
- using System.IO;
- public partial class TestRenderControl : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- }
- public override void VerifyRenderingInServerForm(Control control)
- {
- //如果control是GridView,跳过验证,这里最好的验证是验证control的Id
- //if (control is GridView || control is RadioButton)
- //{
- // return;
- //}
- //base.VerifyRenderingInServerForm(control);
- }
- protected void Submit_Click(object sender, EventArgs e)
- {
- WebUserControl control = LoadControl("WebUserControl.ascx") as WebUserControl;
- control.BindGridView();
- StringWriter tw = new StringWriter();
- HtmlTextWriter writer = new HtmlTextWriter(tw);
- control.RenderControl(writer);
- DIV_Test.InnerHtml = writer.InnerWriter.ToString();
- }
- }
转自:http://blog.csdn.net/llxchen/archive/2008/12/16/3529174.aspx