即使GridView在表单标记内,GridView也必须放在带有runat =“server”的表单标记内

时间:2011-06-14 12:41:53

标签: c# .net asp.net

<form runat="server" id="f1">
    <div runat="server" id="d">
        grid view:
        <asp:GridView runat="server" ID="g">
        </asp:GridView>
    </div>

    <asp:TextBox runat="server" ID="t" TextMode="MultiLine" Rows="20" Columns="50"></asp:TextBox>
</form>

代码背后:

public partial class ScriptTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        g.DataSource = new string[] { "a", "b", "c" };
        g.DataBind();

        TextWriter tw = new StringWriter();
        HtmlTextWriter h = new HtmlTextWriter(tw);    
        d.RenderControl(h);
        t.Text = tw.ToString();
    }
}

即使GridView位于带有runat =“server”的from标签内,我仍然会收到此错误。

有什么线索吗?

5 个答案:

答案 0 :(得分:158)

您正在调用GridView.RenderControl(htmlTextWriter),因此该页面引发了一个异常,即Server-Control是在Form外部呈现的。

你可以通过覆盖VerifyRenderingInServerForm

来避免这种行为
public override void VerifyRenderingInServerForm(Control control)
{
  /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
     server control at run time. */
}

请参阅herehere

答案 1 :(得分:26)

重写VerifyRenderingInServerForm的替代方法是在执行渲染时从控件集合中删除网格,然后在页面加载之前完成后将其添加回来。如果你想要一些通用的帮助方法来获取网格html,这很有用,因为你不必记得添加覆盖。

Control parent = grid.Parent;
int GridIndex = 0;
if (parent != null)
{
    GridIndex = parent.Controls.IndexOf(grid);
    parent.Controls.Remove(grid);
}

grid.RenderControl(hw);

if (parent != null)
{
    parent.Controls.AddAt(GridIndex, grid);
}

避免覆盖的另一种方法是:

grid.RenderBeginTag(hw);
grid.HeaderRow.RenderControl(hw);
foreach (GridViewRow row in grid.Rows)
{
    row.RenderControl(hw);
}
grid.FooterRow.RenderControl(hw);
grid.RenderEndTag(hw);

答案 2 :(得分:13)

在你的Page_Load添加之后:

public override void VerifyRenderingInServerForm(Control control)
{
    //base.VerifyRenderingInServerForm(control);
}

请注意,我在该功能中没有做任何事情。

编辑:蒂姆回答了同样的事情。 :) 您还可以找到答案Here

答案 3 :(得分:1)

只想添加另一种方法。我已经看到各种相关线程上的多个人询问您是否可以使用VerifyRenderingInServerForm而不将其添加到父页面。

你实际上可以这样做,但这有点像躲闪。

首先创建一个新的Page类,如下所示:

public partial class NoRenderPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    { }

    public override void VerifyRenderingInServerForm(Control control)
    {
        //Allows for printing
    }

    public override bool EnableEventValidation
    {
        get { return false; }
        set { /*Do nothing*/ }
    }
}

不需要与之关联.ASPX。

然后在您希望呈现的控件中,您可以执行以下操作。

    StringWriter tw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(tw);

    var page = new NoRenderPage();
    page.DesignerInitialize();
    var form = new HtmlForm();
    page.Controls.Add(form);
    form.Controls.Add(pnl);
    controlToRender.RenderControl(hw);

现在您已将原始控件呈现为HTML。如果需要,将控件添加回原始位置。您现在已经呈现了HTML,页面正常,并且没有对页面本身进行任何更改。

答案 4 :(得分:1)

这是我的代码

protected void btnExcel_Click(object sender, ImageClickEventArgs e)
    {
        if (gvDetail.Rows.Count > 0)
        {
            System.IO.StringWriter stringWrite1 = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter htmlWrite1 = new HtmlTextWriter(stringWrite1);
            gvDetail.RenderControl(htmlWrite1);

            gvDetail.AllowPaging = false;
            Search();
            sh.ExportToExcel(gvDetail, "Report");
        }
    }

    public override void VerifyRenderingInServerForm(Control control)
    {
        /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
           server control at run time. */
    }