GridView deve essere posizionato all'interno di un tag del modulo con runat = "server" anche dopo che GridView si trova all'interno di un tag del modulo


86
<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>

Codice dietro:

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

Anche GridView si trova all'interno di un tag from con runat = "server", ancora ricevo questo errore.

Qualche indizio per favore?


2
L'ho già visto se qualcuno utilizza una pagina master che ha già un tag form (che potrebbe o non potrebbe già essere dichiarato runat="server"nel suo <form>tag). Solo un pensiero ...
lhan

@ Lloyd: ma non ho alcuna pagina master, ho creato questa pagina solo per testare questo errore.
teenup

Ciao, ho copiato il tuo codice ma non riesco a replicare il problema. Per favore, puoi inserire l'intero contenuto del file (ogni riga) nella tua domanda o incollarlo? Grazie
christofr

Risposte:


174

Stai chiamando GridView.RenderControl(htmlTextWriter), quindi la pagina solleva un'eccezione che un Server-Control è stato reso al di fuori di un Form.

È possibile evitare questa esecuzione sovrascrivendo VerifyRenderingInServerForm

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

Vedi qui e qui .


Ho un GridView i cui contenuti voglio rendere in un messaggio di posta elettronica, ecco perché ho bisogno di renderlo fuori forma. Non posso ignorare questo metodo perché la pagina host è di Sharepoint. My Grid è un controllo utente all'interno di una web part nella pagina sharepoint.
teenup

Inoltre, quando aggiungo quel GridView direttamente a un HtmlForm in modo dinamico e quindi lo renderizzo, il rendering viene eseguito perfettamente. Ciò significa che richiede solo la presenza di un modulo esterno alla griglia. Ma, quando aggiungo dinamicamente quel DIV a HtmlForm, questo errore si ripresenta, sebbene Grid sia un figlio di DIV e anche aggiunto a HtmlForm insieme ad esso.
teenup

questo non funzionerà se la tua griglia è all'interno di un controllo utente .ascx. in tal caso vedere la risposta di Chris Mullins di seguito. Ho usato sia le tecniche di Tim che quelle di Chris e funzionano alla grande.
Taylor Brown

Adoro una soluzione elegante! Mi emoziona: D
Nikolay

3
Ha funzionato alla grande. Solo un avvertimento potresti ricevere un errore che dice "RegisterForEventValidation può essere chiamato solo durante Render ();" In tal caso, assicurati di impostare EventValidation su false nel markup della pagina.
Al Belmondo

29

Un'alternativa all'override di VerifyRenderingInServerForm consiste nel rimuovere la griglia dalla raccolta di controlli mentre si esegue il rendering, quindi aggiungerla di nuovo al termine prima del caricamento della pagina. Questo è utile se vuoi avere qualche metodo di aiuto generico per ottenere l'html della griglia perché non devi ricordarti di aggiungere l'override.

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

Un'altra alternativa per evitare l'override è fare questo:

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

Abile!! Lo proverò domani.
teenup

quando si tenta di eseguire il rendering della griglia all'interno di un controllo utente asp (.ascx), l'utilizzo del primo metodo ha funzionato alla grande per me.
Taylor Brown

3
1.Non funziona se gridview contiene controlli come LinkButton - fornisce il 'Controllo di tipo' LinkButton 'deve essere inserito all'interno di un tag del form con runat = server' errore. 2.Puoi spiegare per favore perché questa tecnica funziona?
BornToCode

@BornToCode Disabilita l'ordinamento per il tuo gridview nel codice.
Adi Solar

14

Subito dopo il tuo Page_Load aggiungi questo:

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

Nota che non faccio nulla nella funzione.

EDIT: Tim ha risposto la stessa cosa. :) Puoi anche trovare la risposta qui


2

Voglio solo aggiungere un altro modo per farlo. Ho visto più persone su vari thread correlati chiedere se è possibile utilizzare VerifyRenderingInServerForm senza aggiungerlo alla pagina padre.

In realtà puoi farlo ma è un po 'un pasticcio.

Prima di tutto crea una nuova classe Page che assomigli a quanto segue:

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

Non è necessario che sia associato un .ASPX.

Quindi nel controllo che desideri rendere puoi fare qualcosa come il seguente.

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

Ora hai il tuo controllo originale reso come HTML. Se necessario, aggiungere nuovamente il controllo alla sua posizione originale. Ora hai reso l'HTML, la pagina normale e nessuna modifica alla pagina stessa.


@DanielEdwards cosa fa per te DesignerInitialize ()?
JJS

Funziona ma avevo bisogno di usarlo HttpContext.Current.Server.Execute(page, writer, false);per scrivere l'HTML - la chiamata controlToRender.RenderControl(hw);non sollevava nessuno degli eventi di controllo, ad esempio Page_Loadcosì mentre il controllo era in rendering, era vuoto.
DGibbs

0

Ecco il mio codice

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

Perché hai aggiunto questa risposta 5 anni dopo la risposta? Ed è la stessa risposta.
Mukus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.