"La colección de controles no se puede modificar porque el control contiene bloques de código"


370

Estoy tratando de crear un control de usuario simple que sea un control deslizante. Cuando agrego un AjaxToolkit SliderExtender al control de usuario obtengo este error (* & $ # () @ #:

Server Error in '/' Application. The Controls collection cannot be modified because the control contains code blocks (i.e. `<% ... %>`). Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. `<% ... %>`).

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): The Controls collection cannot be modified because the control contains code blocks (i.e. `<% ... %>`).]    System.Web.UI.ControlCollection.Add(Control child) +8677431    AjaxControlToolkit.ScriptObjectBuilder.RegisterCssReferences(Control control) in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ScriptObjectBuilder.cs:293 AjaxControlToolkit.ExtenderControlBase.OnLoad(EventArgs e) in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs:306 System.Web.UI.Control.LoadRecursive()
+50    System.Web.UI.Control.LoadRecursive()
+141    System.Web.UI.Control.LoadRecursive()
+141    System.Web.UI.Control.LoadRecursive()
+141    System.Web.UI.Control.LoadRecursive()             
+141    System.Web.UI.Control.LoadRecursive()
+141    System.Web.UI.Control.LoadRecursive()
+141    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627


Version Information: Microsoft .NET Framework Version:2.0.50727.3074; ASP.NET Version:2.0.50727.3074

Intenté poner un marcador de posición en el control del usuario y agregar el cuadro de texto y el extensor del control deslizante al marcador de posición mediante programación y todavía recibo el error.

Aquí está el código simple:

<table cellpadding="0" cellspacing="0" style="width:100%">
    <tbody>
        <tr>
            <td></td>
            <td>
                <asp:Label ID="lblMaxValue" runat="server" Text="Maximum" CssClass="float_right" />
                <asp:Label ID="lblMinValue" runat="server" Text="Minimum" />
            </td>
        </tr>
        <tr>
            <td style="width:60%;">
                <asp:CheckBox ID="chkOn" runat="server" />
                <asp:Label ID="lblPrefix" runat="server" />:&nbsp;
                <asp:Label ID="lblSliderValue" runat="server" />&nbsp;
                <asp:Label ID="lblSuffix" runat="server" />
            </td>
            <td style="text-align:right;width:40%;">                

                    <asp:TextBox ID="txtSlider" runat="server" Text="50" style="display:none;" />
                    <ajaxToolkit:SliderExtender ID="seSlider" runat="server" 
                        BehaviorID="seSlider" 
                        TargetControlID="txtSlider" 
                        BoundControlID="lblSliderValue" 
                        Orientation="Horizontal" 
                        EnableHandleAnimation="true" 
                        Length="200" 
                        Minimum="0" 
                        Maximum="100" 
                        Steps="1" />

            </td>
        </tr>
    </tbody>
</table>

¿Cuál es el problema?


11
Lo que me estaba causando este error era usar <% = Resolve (); %> dentro de las etiquetas <script> y <link>. Finalmente arreglé esto. En lugar de eliminar el código ofensivo en la etiqueta principal que generalmente causa este error. Simplemente coloque todo el código ofensivo en una etiqueta <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
Daniel P

stackoverflow.com/questions/4995274/… Contiene una explicación más larga para la @Daniel Psugerencia.
lko

Respuestas:


498

Primero, inicie el bloque de código con <% # en lugar de <% =:

<head id="head1" runat="server">
  <title>My Page</title>
  <link href="css/common.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="<%# ResolveUrl("~/javascript/leesUtils.js") %>"></script>
</head>

Esto cambia el bloque de código de un bloque de código Response.Write a una expresión de enlace de datos.
Dado que las <%# ... %>expresiones de enlace de datos no son bloques de código, el CLR no se quejará. Luego, en el código de la página maestra, agregaría lo siguiente:

protected void Page_Load(object sender, EventArgs e)
{
  Page.Header.DataBind();    
}

No obtengo este error, pero estoy usando la notación =. Sin embargo: he visto que mi código falla con el problema descrito anteriormente. ¿Qué puede causar eso (de por qué funciona bien conmigo)?
doekman

3
Parecía comenzar a tener este problema después de cambiar a ASP.NET 4. ¿Está aislado del nuevo marco?
Corgalore

3
Se resuelve cuando copio y pego mi código Java Script en la parte inferior de la página. En el anterior se coloca en la etiqueta HEAD.
Miank

1
Este es un error tan extraño con .NET. ¿Por qué en #lugar de =? Nunca lo entenderé, lo he estado haciendo durante años, ¡pero ojalá supiera POR QUÉ!
Mark Pieszak - Trilon.io

1
¡Héroes sin capa si existen!
Julián

253

También me encontré con este problema, pero encontré otra solución.

Descubrí que envolver los bloques de código con un asp: PlaceHolder-tag resuelve el problema.

<asp:PlaceHolder runat="server">
  <meta name="ROBOTS" content="<%= this.ViewData["RobotsMeta"] %>" />
</asp:PlaceHolder>

(El CMS que estoy usando se está insertando en la sección de cabecera de algún código detrás que me restringió de agregar bloques de control personalizados con información diversa como metaetiquetas, etc., por lo que esta es la única forma en que funciona para mí).


11
Increíble. Como usuario anterior de los controles de Telerik, a menudo usaba su "RadCodeBlock" para el mismo propósito, pero siempre me molestaba el hecho de que no sabía nada más aparte de eso (o como otros han mencionado, mover el código a un etiqueta hecha para ejecutarse en el lado del servidor). Nunca supe que estos marcadores de posición podrían tener contenido dentro de ellos. ¡Gracias!
JayC

1
En realidad, gracias a @JayC, RadCodeBlock fue la única sugerencia en esta página que funcionó con el código que heredé, por varias razones.
Shiser

Esto también ocurre con los controles DevExpress registrados. Tengo dos aplicaciones web con código, configuración y páginas maestras casi idénticas. Solo el que tiene DevExpress requiere una solución como esta. Creo que es algo que tiene que ver con su controlador HTTP, ensambles de recursos o algo así que arruina la tubería. Nos estamos alejando de las bibliotecas de terceros ahora a favor de JQuery y MVC, que le permite evitar códigos / controladores complejos del lado del servidor.
Tony Wall

De hecho, es suficiente envolverlo con <div runat = "server"> <% = (...)%> </div>
Zbigniew Wiadro

55
@Teomanshipahi En realidad es bastante simple: el uso de bloques de código dentro de un contenedor significa que ya no puede actualizar Controlsese contenedor. Esto básicamente explota este comportamiento, poniendo el bloque de código en un recipiente separado - por lo que el error sólo aparecería si desea modificar Controlsde la PlaceHolder, en lugar del control de los padres. PlaceHolderes una gran opción para esto, porque no tiene ningún código propio (a diferencia de, digamos Panelo <div runat="server">). Aunque generalmente lo uso al revés, coloque los controles que necesito modificar PlaceHolder.
Luaan

55

Puedo confirmar que mover el javascript con <% %>etiquetas desde la cabeza a la etiqueta del formulario corrige este error

http://italez.wordpress.com/2010/06/22/ajaxcontroltoolkit-calendarextender-e-strana-eccezione/


1
Sí, recién confirmado, eliminar las etiquetas ASP <%%> de la cabeza corrige este error.
Corgalore

+1, confirmado también. Para mí, aunque el guión problemático estaba fuera de los elementos head y form.
user420667

Confirmado. Funciona como un encanto para mí. Simplemente no olvides revisar los scripts en tu página maestra ya que este fue el que me estaba causando problemas y pasé como media hora antes de darme cuenta de que no era mi aspx: P
Luis Hernández

Sí, esto también funcionó para mí, pero ¿por qué? ¿La etiqueta <HEAD> en un archivo maestro debe ser únicamente para el archivo maestro y no para archivos sub-aspx? Pregunto porque estoy tratando de ejecutar el código JS en una página sub-aspx que reside en el archivo maestro.
Fandango68

31

Coloque el javascript debajo de una etiqueta div.

<div runat="server"> //div tag must have runat server
  //Your Jave script code goes here....
</div>

¡Funcionará!


55
O mejor, use un marcador de posición para que no se genere código html adicional.
Chris Haines

1
Esto funciona, aunque Visual Studio dice que viola el estándar HTML5 al anidar un <div> dentro de un <head>.
Adi Inbar

En mi humilde opinión, no es la mejor solución si HTML5 no valida, evite div en la headsección.
PreguntonCojoneroCabrón

8

puede hacer la misma funcionalidad si está utilizando el administrador de scripts en su página. solo tienes que registrar el script como este

<asp:ScriptManager ID="ScriptManager1" runat="server" LoadScriptsBeforeUI="true"   EnablePageMethods="true">  
<Scripts>
      <asp:ScriptReference Path="~/Styles/javascript/jquery.min.js" />
</Scripts>
</asp:ScriptManager>

ScriptManagerNo agregar guiones en la sección de cabecera ?
Kiquenet

5

Tuve el mismo problema en el control de usuario. Mi página que alojaba el control tenía comentarios en la etiqueta principal, eliminé esos comentarios, todo funcionó después. Algunas publicaciones también sugieren eliminar los guiones de la cabeza y colocarlos en el cuerpo.


5

Intenté usar <%# %>sin éxito. Luego cambié Page.Header.DataBind();mi código this.Header.DataBind();y funcionó bien.


4

En mi caso, he reemplazado <%= %>con <%# %>, y funcionó!


3

Mantenga el código del script java dentro de la etiqueta del cuerpo

<body> 
   <script type="text/javascript">
   </script>
</body>

2

La técnica de enlace de datos "<% #" no funcionará directamente dentro de las etiquetas <link> en la etiqueta <head>:

<head runat="server">

  <link rel="stylesheet" type="text/css" 
        href="css/style.css?v=<%# My.Constants.CSS_VERSION %>" />

</head>

El código anterior evaluará a

<head>

  <link rel="stylesheet" type="text/css" 
        href="css/style.css?v=&lt;%# My.Constants.CSS_VERSION %>" />

</head>

En su lugar, debe hacer lo siguiente (tenga en cuenta las dos comillas dobles dentro):

<head runat="server">

  <link rel="stylesheet" type="text/css" 
        href="css/style.css?v=<%# "" + My.Constants.CSS_VERSION %>" />

</head>

Y obtendrá el resultado deseado:

<head>

  <link rel="stylesheet" type="text/css" href="css/style.css?v=1.5" />

</head>

2

Tuve este problema, pero no a través del encabezado. Mi marcador de posición estaba en el cuerpo. Así que reemplacé todo <%=con <%#e hice

protected void Page_Load(object sender, EventArgs e)
{
    Page.Header.DataBind();    
}

Y funcionó.


1

Una forma alternativa es hacer que otra página .aspx actúe como la página a la que desea vincular.

Así es como se ve el encabezado de la página maestra:

<head runat="server">
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
    <link href="CSS/AccordionStyles.aspx" rel="stylesheet" type="text/css" />
</head>

El formulario .aspx referenciado contiene su contenido:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AccordionStyles.aspx.cs" Inherits="IntranetConnectCMS.CSS.AccordionStyles" %>
.AccordionHeader
{
    cursor: pointer;
    background-image: url(<%=ResolveUrl("~/Images/Backgrounds/AccordionPaneHeaderClosed.png") %>);
    background-repeat: no-repeat;
}

.AccordionHeaderSelected
{
    cursor: pointer;
    background-image: url(<%=ResolveUrl("~/Images/Backgrounds/AccordionPaneHeaderOpen.png") %>);
    background-repeat: no-repeat;
}
.AccordionContent
{
    background-image: url(<%=ResolveUrl("~/Images/Backgrounds/AccordionPaneContent.png") %>);
    background-repeat: no-repeat;
}

Finalmente, necesita la página .aspx para decirle al navegador que está enviando contenido CSS:

protected void Page_Load(object sender, EventArgs e)
{
    Response.ContentType = "text/css";
}

1

También enfrenté el mismo problema. Encontré las soluciones como las siguientes.

Solución 1: mantuve mi etiqueta de script en el cuerpo.

<body>
   <form> . . . .  </form>
    <script type="text/javascript" src="<%= My.Working.Common.Util.GetSiteLocation()%>Scripts/Common.js"></script> </body>

Ahora se resolverán los conflictos relacionados con las etiquetas.

Solución 2:

También podemos resolver esta una de las soluciones anteriores, como Reemplazar el bloque de código con <% # en lugar de <% = Pero el problema es que solo dará una ruta relativa . Si quieres un camino realmente absoluto , no funcionará.

La solución 1 me funciona. Lo siguiente es tu elección.


1

Tuve el mismo problema, pero no tenía nada que ver con JavaScript. Considera este código:

<input id="hdnTest" type="hidden" value='<%= hdnValue %>' />
<asp:PlaceHolder ID="phWrapper" runat="server"></asp:PlaceHolder>
<asp:PlaceHolder ID="phContent" runat="server" Visible="false">
    <b>test content</b>
</asp:PlaceHolder>

En esta situación, obtendrá el mismo error a pesar de que PlaceHolders no tiene ningún bloque de código dañino, esto sucede debido al control que no es del servidor hdnTest usa bloques de código.

Simplemente agregue runat = server al hdnTest y el problema está resuelto.


1

Resolví un error similar a esto poniendo el <script>interior contentplaceholderdentro del interior en <head>lugar de colocar el <script>exterior contentplaceholderdentro de dicho<head>


1

Tuve el mismo problema con diferentes circunstancias.
Tenía un elemento simple dentro de la etiqueta del cuerpo.
La solución fue:

<asp:PlaceHolder ID="container" runat="server">
    <a id="child" href="<%# variable %>">Change me</a>
</asp:PlaceHolder>
protected new void Page_Load(object sender, EventArgs e)
{    
    Page.Form.DataBind(); // I neded to Call DataBind on Form not on Header
    container.InnerHtml = "Simple text";
}

1

Tuve el mismo problema con mi sistema, eliminé el código JavaScript de mi página y lo puse en el cuerpo justo antes de cerrar la etiqueta del cuerpo


0

En algunos casos, ResolveUrl y ResolveClientUrl funcionan, pero no siempre, especialmente en el caso de los archivos de script js. Lo que sucede es que funciona para algunas páginas, pero cuando navega a otras páginas puede que no funcione debido a la ruta relativa de esa página en particular.

Finalmente, mi sugerencia es siempre hacer una revisión completa de las páginas de su sitio para ver si todas sus referencias de JavaScript están bien o no. Abra su sitio en Google Chrome -> haga clic derecho en la página -> haga clic en ver página de origen -> aparece HTML -> ahora haga clic en sus hipervínculos JS; si funciona bien, debería abrir el archivo js en otra ventana del navegador, de lo contrario no se abrirá.


0

Intente escribir su código de script java fuera de la etiqueta de encabezado definitivamente funcionará. Se resuelve cuando copio y pego mi código de Java Script en la parte inferior de la página. En el anterior, se coloca en la etiqueta HEAD ahora justo antes de cerrar la etiqueta del formulario.

    </div>
        <script>
                    function validate() {
                        try {

                        var username = document.getElementById("<%=txtUserName.ClientID%>").value;
                        var password = document.getElementById("<%=txtPWD.ClientID%>").value;

                            if (username == "" && password == "")
                                alert("Enter Username and Passowrd");
                            else {
                                if (username == "")
                                    alert("Enter Username");
                                else if (password == "")
                                    alert("Enter Password");
                            }

                        }

                    catch (err) {
                    }
                }
                </script>
</form>

0

Elimine la parte que tiene etiquetas de servidor y colóquela en otro lugar si desea agregar controles dinámicos desde el código detrás

Eliminé mi JavaScript de la sección principal de la página y lo agregué al cuerpo de la página y lo puse a funcionar


0

En mi caso, recibí este error porque estaba configurando incorrectamente InnerText en un div con html dentro.

Ejemplo:

SuccessMessagesContainer.InnerText = "";

   <div class="SuccessMessages ui-state-success" style="height: 25px; display: none;" id="SuccessMessagesContainer" runat="server">
      <table>
         <tr>
            <td style="width: 80px; vertical-align: middle; height: 18px; text-align: center;">
               <img src="<%=Image_success_icn %>" style="margin: 0 auto; height: 18px;
                  width: 18px;" />
            </td>
            <td id="SuccessMessage" style="vertical-align: middle;" class="SuccessMessage" runat="server" >
            </td>
         </tr>
      </table>
   </div>

-1

Las etiquetas <%= %>no funcionan en una etiqueta con runat="server". Mueva su código con <%= %>en runat="server"a otro tag ( body, head, ...), o eliminar runat="server"del envase.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.