GridView harus ditempatkan di dalam tag formulir dengan runat = "server" bahkan setelah GridView berada di dalam tag formulir

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>

Kode di belakang:

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();
    }
}

Bahkan GridView berada dalam tag from dengan runat = "server", saya masih mendapatkan kesalahan ini.

Ada petunjuk?

remaja
sumber
2
Saya telah melihat ini sebelumnya jika seseorang menggunakan halaman Master yang sudah memiliki tag formulir (yang mungkin atau mungkin belum mendeklarasikan runat="server"di <form>tag itu). Hanya berpikir ...
lhan
@ Lloyd: Tapi saya tidak memiliki Halaman Master, saya telah membuat halaman ini hanya untuk menguji kesalahan ini.
remaja
Hai, saya menyalin kode Anda tetapi tidak dapat mereplikasi masalah. Bisakah Anda memasukkan seluruh konten file (setiap baris) ke dalam pertanyaan Anda, atau Pastebin? Terima kasih
christofr

Jawaban:

176

Anda memanggil GridView.RenderControl(htmlTextWriter), karena itu halaman memunculkan pengecualian bahwa Kontrol-Server dibuat di luar Formulir.

Anda dapat menghindari eksekusi ini dengan mengganti VerifyRenderingInServerForm

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

Lihat disini dan disini .

Tim Schmelter
sumber
Saya memiliki GridView yang isinya ingin saya render menjadi Pesan Email, itulah mengapa saya perlu membuatnya keluar dari bentuk. Saya tidak dapat mengganti metode ini karena halaman host adalah Sharepoint. My Grid adalah Usercontrol di dalam komponen web di halaman SharePoint.
remaja
Juga, ketika saya menambahkan GridView itu langsung ke HtmlForm secara dinamis, dan kemudian merendernya, itu ditampilkan dengan sempurna. Artinya hanya membutuhkan adanya form diluar grid. Tapi, ketika saya menambahkan DIV itu ke HtmlForm secara dinamis, kesalahan ini muncul lagi, meskipun Grid adalah anak dari DIV dan juga ditambahkan ke HtmlForm bersamaan dengannya.
remaja
ini tidak akan berfungsi jika kisi Anda berada di dalam kontrol pengguna .ascx. dalam hal ini lihat jawaban Chris Mullins di bawah. Saya telah menggunakan teknik Tim dan Chris dan mereka bekerja dengan baik.
Taylor Brown
Saya suka solusi yang elegan! Membuat saya bersemangat: D
Nikolay
3
Bekerja dengan baik. Sekadar pemberitahuan, Anda mungkin mendapatkan pesan kesalahan yang mengatakan "RegisterForEventValidation hanya dapat dipanggil selama Render ();" Jika demikian, set pastikan untuk menyetel EventValidation ke false di markup untuk halaman.
Al Belmondo
29

Alternatif untuk menimpa VerifyRenderingInServerForm adalah dengan menghapus kisi dari koleksi kontrol saat Anda melakukan render, lalu menambahkannya kembali saat Anda selesai sebelum halaman dimuat. Ini berguna jika Anda ingin memiliki beberapa metode pembantu umum untuk mendapatkan html grid karena Anda tidak perlu ingat untuk menambahkan timpaan.

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);
}

Alternatif lain untuk menghindari penggantian adalah dengan melakukan ini:

grid.RenderBeginTag(hw);
grid.HeaderRow.RenderControl(hw);
foreach (GridViewRow row in grid.Rows)
{
    row.RenderControl(hw);
}
grid.FooterRow.RenderControl(hw);
grid.RenderEndTag(hw);
Chris Mullins
sumber
Gesit!! Saya akan mencobanya besok.
remaja
ketika mencoba merender grid di dalam kontrol pengguna asp (.ascx), menggunakan metode pertama bekerja sangat baik untuk saya.
Taylor Brown
3
1. Tidak berfungsi jika gridview berisi kontrol seperti LinkButton - ini memberikan 'Kontrol jenis' LinkButton 'harus ditempatkan di dalam tag formulir dengan kesalahan runat = server'. 2. Bisakah Anda menjelaskan mengapa teknik ini berhasil?
BornToCode
@BornToCode Nonaktifkan pengurutan untuk tampilan jaringan Anda dalam kode.
Adi Solar
14

Tepat setelah Page_Load Anda tambahkan ini:

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

Perhatikan bahwa saya tidak melakukan apa pun dalam fungsi tersebut.

EDIT: Tim menjawab hal yang sama. :) Anda juga bisa menemukan jawabannya disini

Ivan Nikolov
sumber
2

Hanya ingin menambahkan cara lain untuk melakukan ini. Saya telah melihat banyak orang di berbagai utas terkait menanyakan apakah Anda dapat menggunakan VerifyRenderingInServerForm tanpa menambahkannya ke halaman induk.

Anda sebenarnya dapat melakukan ini tetapi itu sedikit berlebihan.

Pertama buat kelas Halaman baru yang terlihat seperti berikut:

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

Tidak perlu memiliki .ASPX yang terkait dengannya.

Kemudian dalam kontrol yang ingin Anda render, Anda dapat melakukan hal seperti berikut.

    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);

Sekarang Anda memiliki kontrol asli yang dirender sebagai HTML. Jika perlu, tambahkan kontrol kembali ke posisi semula. Anda sekarang memiliki HTML yang dirender, halaman seperti biasa dan tidak ada perubahan pada halaman itu sendiri.

Daniel Edwards
sumber
@DanielEdwards apa yang DesignerInitialize () lakukan untuk Anda?
JJS
Ini berfungsi tetapi saya perlu menggunakan HttpContext.Current.Server.Execute(page, writer, false);untuk menulis HTML - pemanggilan controlToRender.RenderControl(hw);tidak memunculkan salah satu peristiwa kontrol misalnya Page_Loadjadi ketika kontrol sedang dirender, itu kosong.
DGibbs
0

Inilah Kode Saya

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. */
    }
vipin
sumber
Mengapa Anda menambahkan jawaban ini 5 tahun setelah dijawab? Dan itu adalah jawaban yang sama.
Mukus