ต้องวาง GridView ไว้ในแท็กฟอร์มที่มี runat =“ เซิร์ฟเวอร์” แม้ว่า GridView จะอยู่ในแท็กแบบฟอร์มก็ตาม


87
<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 = "เซิร์ฟเวอร์" แต่ฉันก็ยังได้รับข้อผิดพลาดนี้

กรุณาแจ้งเบาะแสใด ๆ


2
ฉันเคยเห็นสิ่งนี้มาก่อนหากมีคนใช้หน้าต้นแบบที่มีแท็กแบบฟอร์มอยู่แล้ว (ซึ่งอาจจะประกาศrunat="server"ใน<form>แท็กหรือไม่ก็ได้) แค่คิด ...
lhan

@Lloyd: แต่ฉันไม่มี Master Page ฉันสร้างเพจนี้เพื่อทดสอบข้อผิดพลาดนี้เท่านั้น
teenup

สวัสดีฉันคัดลอกรหัสของคุณ แต่ไม่สามารถจำลองปัญหาได้ คุณช่วยใส่เนื้อหาไฟล์ทั้งหมด (ทุกบรรทัด) ลงในคำถามของคุณหรือ Pastebin ได้ไหม ขอบคุณ
christofr

คำตอบ:


176

คุณกำลังโทรGridView.RenderControl(htmlTextWriter)ด้วยเหตุนี้เพจจึงมีข้อยกเว้นว่าการควบคุมเซิร์ฟเวอร์ถูกแสดงผลภายนอกแบบฟอร์ม

คุณสามารถหลีกเลี่ยงการดำเนินการนี้ได้โดยการแทนที่VerifyRenderingInServerForm

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

ดูที่นี่และที่นี่


ฉันมี GridView ที่มีเนื้อหาที่ฉันต้องการแสดงเป็นข้อความอีเมลนั่นคือเหตุผลที่ฉันต้องแสดงผลในรูปแบบ ฉันไม่สามารถแทนที่วิธีนี้ได้เนื่องจากหน้าโฮสต์เป็นของ Sharepoint My Grid เป็น Usercontrol ภายใน web part ในหน้า sharepoint
teenup

นอกจากนี้เมื่อฉันเพิ่ม GridView นั้นโดยตรงไปยัง HtmlForm แบบไดนามิกแล้วแสดงผลมันจะแสดงผลอย่างสมบูรณ์แบบ ซึ่งหมายความว่าจำเป็นต้องมีฟอร์มนอกตารางเท่านั้น แต่เมื่อฉันเพิ่ม DIV นั้นลงใน HtmlForm แบบไดนามิกข้อผิดพลาดนี้เกิดขึ้นอีกครั้งแม้ว่า Grid จะเป็นลูกของ DIV และยังเพิ่มไปยัง HtmlForm ด้วย
teenup

สิ่งนี้จะไม่ทำงานหากกริดของคุณอยู่ในตัวควบคุมผู้ใช้. ascx ในกรณีนี้ให้ดูคำตอบของ Chris Mullins ด้านล่าง ฉันใช้ทั้งเทคนิคของทิมและคริสและมันก็ใช้ได้ผลดี
Taylor Brown

ฉันชอบโซลูชันที่หรูหรา! ทำให้ฉันรู้สึกตื่นเต้น: D
Nikolay

3
ทำงานได้ดีมาก เพียงแค่แจ้งให้ทราบล่วงหน้าคุณอาจได้รับข้อผิดพลาดว่า "RegisterForEventValidation สามารถเรียกได้ในระหว่าง Render () เท่านั้น" หากตั้งค่าไว้ตรวจสอบให้แน่ใจว่าได้ตั้งค่า EventValidation เป็นเท็จในมาร์กอัปสำหรับเพจ
Al Belmondo

29

อีกทางเลือกหนึ่งในการแทนที่ 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);

แอดทรอยต์ !! ฉันจะลองพรุ่งนี้
teenup

เมื่อพยายามเรนเดอร์กริดภายในการควบคุมผู้ใช้ asp (.ascx) การใช้วิธีที่ 1 ได้ผลดีสำหรับฉัน
Taylor Brown

3
1. จะไม่ทำงานหาก gridview มีตัวควบคุมเช่น LinkButton - จะต้องวาง 'Control of type' LinkButton 'ไว้ในแท็กฟอร์มที่มีข้อผิดพลาด runat = server 2. คุณช่วยอธิบายได้ไหมว่าทำไมเทคนิคนี้ถึงใช้ได้ผล?
BornToCode

@BornToCode ปิดการใช้งานการเรียงลำดับสำหรับ gridview ของคุณในโค้ด
Adi Solar

14

หลังจาก Page_Load ของคุณเพิ่มสิ่งนี้:

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

โปรดทราบว่าฉันไม่ได้ทำอะไรในฟังก์ชันนี้

แก้ไข: ทิมตอบในสิ่งเดียวกัน :) คุณยังสามารถหาคำตอบได้ที่นี่


2

เพียงแค่ต้องการเพิ่มวิธีการอื่นในการทำเช่นนี้ ฉันเคยเห็นหลายคนในหัวข้อที่เกี่ยวข้องต่างๆถามว่าคุณสามารถใช้ VerifyRenderingInServerForm โดยไม่ต้องเพิ่มลงในเพจหลักได้หรือไม่

คุณสามารถทำได้จริง แต่มันเป็นเรื่องเล็กน้อย

ก่อนอื่นให้สร้างคลาสเพจใหม่ซึ่งมีลักษณะดังนี้:

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 หน้าตามปกติและไม่มีการเปลี่ยนแปลงในหน้า


@DanielEdwards DesignerInitialize () ทำอะไรให้คุณบ้าง?
JJS

ใช้งานได้ แต่ฉันต้องการใช้HttpContext.Current.Server.Execute(page, writer, false);เพื่อเขียน HTML - การโทรcontrolToRender.RenderControl(hw);ไม่ได้เพิ่มเหตุการณ์การควบคุมใด ๆ เช่นPage_Loadในขณะที่การแสดงผลการควบคุมนั้นว่างเปล่า
DGibbs

0

นี่คือรหัสของฉัน

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. */
    }

ทำไมคุณถึงเพิ่มคำตอบนี้ 5 ปีหลังจากที่ได้รับคำตอบ และก็เป็นคำตอบเดียวกัน
Mukus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.