2011-06-14 28 views
72
<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> 

Código atrás:GridView debe ser colocado dentro de una etiqueta de formulario con runat = "server", incluso después de que el GridView está dentro de una etiqueta de formulario

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

Incluso el GridView se encuentra a partir de la etiqueta con el runat = "servidor", todavía estoy recibiendo este error.

¿Alguna pista por favor?

+2

que he visto esto antes, si alguien está usando una página maestra que ya tiene una etiqueta de formulario (que pueden o no, haber sido declarando 'runat = "server" en' es la etiqueta '

'). Solo un pensamiento ... – lhan

+0

@Lloyd: Pero no tengo ninguna página maestra, he creado esta página para probar solo este error. – teenup

+0

Hola, copié tu código pero no puedo replicar el problema. ¿Puede poner el contenido del archivo completo (cada línea) en su pregunta, o pegarlo? Gracias – christofr

Respuesta

146

Está llamando al GridView.RenderControl(htmlTextWriter), por lo que la página genera una excepción que un Server-Control se procesó fuera de un Formulario.

podría evitar esta execption anulando VerifyRenderingInServerForm

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

Ver here y here.

+0

Tengo un GridView cuyo contenido quiero mostrar en un mensaje de correo electrónico, por eso necesito hacerlo fuera de formato. No puedo anular este método porque la página de host es Sharepoint. My Grid es un Usercontrol dentro de un elemento web en la página sharepoint. – teenup

+0

Además, cuando agrego ese GridView directamente a un HtmlForm dinámicamente, y luego lo renderizo, lo renderiza perfectamente. Esto significa que solo requiere la presencia de un formulario fuera de la grilla. Pero, cuando agrego ese DIV al HtmlForm dinámicamente, aparece nuevamente este error, aunque el Grid es un elemento secundario de DIV y también se agrega a HtmlForm junto con él. – teenup

+0

@Tim Schmelter ... ¡¡eres DIOS !!! ¡¡Gracias!! – DotNetRookie

11

Justo después de su Page_Load añadir lo siguiente:

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

Tenga en cuenta que no hago nada en la función.

EDIT: Tim respondió lo mismo. :) También puede encontrar la respuesta Here

26

Una alternativa a anulando VerifyRenderingInServerForm es quitar la rejilla de la colección de controles mientras usted el render, y luego añadir de nuevo cuando haya terminado antes de que se cargue la página. Esto es útil si desea tener algún método de ayuda genérico para obtener grillas html porque no tiene que recordar agregar la anulación.

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

Otra alternativa para evitar la anulación es hacer esto:

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

Adroit !! Intentaré mañana. – teenup

+0

cuando intento renderizar la grilla dentro de un control de usuario asp (.ascx), usar el primer método me funcionó muy bien. –

+2

1.No funciona si gridview contiene controles como LinkButton - da 'Control de tipo' LinkButton 'debe colocarse dentro de una etiqueta de formulario con error runat = server'. 2. ¿Podría explicar por qué funciona esta técnica? – BornToCode

1

Sólo quiero añadir otra forma de hacer esto. He visto a varias personas en varios hilos relacionados preguntar si puede usar VerifyRenderingInServerForm sin agregarlo a la página principal.

De hecho, puedes hacer esto pero es un poco bodge.

En primer lugar crear una nueva clase de página que será similar a la siguiente:

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

no necesita tener una .ASPX asociada a ella.

Luego, en el control que desea representar, puede hacer algo como lo siguiente.

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

Ahora tiene su control original representado como HTML. Si es necesario, vuelva a agregar el control a su posición original. Ahora tiene el HTML procesado, la página es normal y no tiene cambios en la página.

+0

Demasiado código para lograr algo simple. – SearchForKnowledge

+0

@DanielEdwards ¿qué hace DesignerInitialize() por usted? – JJS

2

Aquí está mi código

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