"A coleção Controls não pode ser modificada porque o controle contém blocos de código"

370

Estou tentando criar um controle de usuário simples que é um controle deslizante. Quando adiciono um AjaxToolkit SliderExtender ao controle do usuário, recebo o erro (* & $ # () @ #:

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

Tentei colocar um espaço reservado no controle de usuário e adicionar programaticamente o extensor de caixa de texto e controle deslizante ao espaço reservado de forma programática e ainda recebo o erro.

Aqui está o código simples:

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

Qual é o problema?

Daniel P
fonte
11
O que estava causando esse erro para mim foi usar o <% = Resolve (); Função%> dentro das tags <script> e <link>. Eu finalmente consertei isso. Em vez de remover o código incorreto na tag head que geralmente causa esse erro. Basta colocar todo o código incorreto em uma tag <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
22409 Daniel P
stackoverflow.com/questions/4995274/… Contém uma explicação mais longa para a @Daniel Psugestão.
Lko 28/11/12

Respostas:

498

Primeiro, inicie o bloco de código com <% # em vez 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>

Isso altera o bloco de código de um bloco de código Response.Write para uma expressão de ligação de dados.
Como as <%# ... %>expressões de ligação de dados não são blocos de código, o CLR não irá reclamar. Em seguida, no código da página mestre, você adicionaria o seguinte:

protected void Page_Load(object sender, EventArgs e)
{
  Page.Header.DataBind();    
}
Jalal El-Shaer
fonte
Não recebo esse erro, mas estou usando a notação =. No entanto: vi meu código falhar com o problema descrito acima. O que pode causar isso (por que está funcionando bem comigo)?
Dokman 28/06/10
3
Eu parecia começar a ter esse problema depois de mudar para o ASP.NET 4. Ele está isolado na nova estrutura?
Corgalore 9/03/11
3
É resolvido quando eu copio e colo meu código Java Script na parte inferior da página. No anterior, ele é colocado na tag HEAD.
Miank
11
Este é um bug tão bizarro com o .NET. Por que ao #invés de =. Eu nunca vou entender esse, faço isso há anos, mas gostaria de saber por que!
Mark Pieszak - Trilon.io
11
Heróis sem capa, se existirem!
Julián
253

Eu acabei de encontrar esse problema também, mas encontrei outra solução.

Descobri que agrupar os blocos de código com uma asp: PlaceHolder-tag resolve o problema.

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

(O CMS que estou usando está inserindo na seção de cabeçalho de algum código por trás do qual me impedia de adicionar blocos de controle personalizados com várias informações, como meta-tags, etc.

Jonas Stensved
fonte
11
Impressionante. Como usuário anterior dos controles da Telerik, eu costumava usar o "RadCodeBlock" para o mesmo objetivo, mas sempre me incomodava com o fato de não saber de nada além disso (ou, como outros já mencionaram, mover o código para um tag criada para executar no lado do servidor). Eu nunca soube que esses espaços reservados poderiam ter conteúdo dentro deles. Obrigado!
JayC
11
Na verdade, obrigado a @JayC, o RadCodeBlock foi a única sugestão nesta página que funcionou com o código que eu herdei, por vários motivos.
shiser
Isso também ocorre com os controles do DevExpress registrados. Eu tenho dois aplicativos da web com código quase idêntico, configuração e páginas mestras. Somente aquele com DevExpress requer uma solução alternativa como esta. Eu acho que tem algo a ver com o manipulador HTTP, assemblies de recursos ou algo assim atrapalhando o pipeline. Agora estamos saindo das bibliotecas de terceiros em favor do JQuery e MVC, o que permite evitar códigos / manipuladores complexos do lado do servidor.
Tony Muro
Na verdade, é o suficiente para envolvê-lo com <div runat = "server"> <% = (...)%> </div> #
Zbigniew Wiadro 17/10
5
@Teomanshipahi Na verdade, é bem simples - usar blocos de código dentro de um contêiner significa que você não pode mais atualizar Controlsesse contêiner. Isso basicamente explora este comportamento, colocando o bloco de código em um recipiente separado - assim que o erro só iria aparecer se você quiser modificar Controlso PlaceHolder, ao invés do controle pai. PlaceHolderé uma ótima opção para isso, porque não possui código próprio (diferente, digamos Panelou <div runat="server">). Embora eu costumo usar o contrário - coloque os controles que preciso modificar PlaceHolder.
Luaan
55

Posso confirmar que mover o javascript com <% %>tags da cabeça para a tag do formulário corrige esse erro

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

ITalez
fonte
11
Sim, confirmado, remover as tags ASP <%%> do cabeçote corrige esse erro.
Corgalore 9/03/11
+1, confirmado também. Para mim, embora o script problemático estivesse fora dos elementos head e form.
user420667
Confirmado. Funciona como um encanto para mim. Só não se esqueça de verificar os scripts em sua página mestre uma vez que este era o único que estava fazendo com que me incomoda e eu passamos como meia hora antes de descobrir que não era o meu aspx: P
Luis Hernández
Sim, isso funcionou para mim também, mas por quê? A marca <HEAD> em um arquivo mestre deve ser puramente para o arquivo mestre e para nenhum arquivo sub-aspx? Eu pergunto porque estou tentando executar o código JS em uma página sub-aspx que reside no arquivo mestre.
Fandango68
31

Coloque o javascript sob uma tag div.

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

Vai dar certo !!

Anup
fonte
5
Ou melhor, use um espaço reservado para que nenhum código html extra seja gerado.
Chris Haines
11
Isso funciona, embora o Visual Studio diga que viola o padrão HTML5 para aninhar um <div> dentro de um <head>.
Adi Inbar
IMHO, não é a melhor solução se o HTML5 não valida, evite div na headseção.
PreguntonCojoneroCabrón
8

você pode fazer a mesma funcionalidade se estiver usando o gerenciador de scripts em sua página. você só precisa registrar o script assim

<asp:ScriptManager ID="ScriptManager1" runat="server" LoadScriptsBeforeUI="true"   EnablePageMethods="true">  
<Scripts>
      <asp:ScriptReference Path="~/Styles/javascript/jquery.min.js" />
</Scripts>
</asp:ScriptManager>
Mohan Prajapati
fonte
ScriptManageradicionar scripts na seção principal ?
Kiquenet 9/09/17
5

Eu tive o mesmo problema no controle do usuário. Minha página que hospedava o controle tinha comentários na tag head, eu os removi, tudo funcionou depois. Algumas postagens também sugerem remover scripts da cabeça e colocá-los no corpo.


fonte
5

Eu tentei usar <%# %>sem sucesso. Então mudei Page.Header.DataBind();meu código para trás this.Header.DataBind();e funcionou bem.

usuario
fonte
4

No meu caso, substituí <%= %>por <%# %>e funcionou!

Iori-kyo
fonte
3

Mantenha o código do script java dentro da tag body

<body> 
   <script type="text/javascript">
   </script>
</body>
Vikash pathak
fonte
2

A técnica de ligação de dados "<% #" não funcionará diretamente dentro das marcas <link> na marca <head>:

<head runat="server">

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

</head>

O código acima avaliará se

<head>

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

</head>

Em vez disso, você deve fazer o seguinte (observe as duas aspas duplas no interior):

<head runat="server">

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

</head>

E você obterá o resultado desejado:

<head>

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

</head>
Perryv
fonte
2

Eu tive esse problema, mas não através do cabeçalho. Meu espaço reservado estava no corpo. Então eu substituí tudo <%=por <%#e fiz

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

e funcionou.

bcr
fonte
1

Uma maneira alternativa é fazer com que outra página .aspx atue como a página à qual você deseja vincular.

É assim que o cabeçalho da Masterpage se parece:

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

O formulário .aspx mencionado contém seu conteúdo:

<%@ 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;
}

Por fim, você precisa da página .aspx para informar ao navegador que está enviando conteúdo CSS:

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

Eu também enfrentei o mesmo problema. Eu encontrei as soluções como a seguir.

Solução 1: eu mantive minha tag de script no corpo.

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

Agora os conflitos relacionados às tags serão resolvidos.

Solução 2:

Também podemos resolver esta uma das soluções acima, como Substituir o bloco de código por <% # em vez de <% = Mas o problema é que ele fornecerá apenas um caminho relativo . Se você quiser um caminho realmente absoluto , não funcionará.

Solução 1 funciona para mim. Em seguida é a sua escolha.

Mihir
fonte
1

Eu tive o mesmo problema, mas não tinha nada a ver com JavaScript. Considere 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>

Nessa situação, você receberá o mesmo erro, embora os PlaceHolders não possuam nenhum bloco de código prejudicial, isso ocorre devido ao controle que não é do servidor, o hdnTest usa blocos de código.

Basta adicionar runat = server ao hdnTest e o problema será resolvido.

homem desesperado
fonte
1

Resolvi um erro semelhante ao colocar o <script>interior de contentplaceholderdentro para dentro em <head>vez de colocar de <script>fora o dito contentplaceholderdentro do<head>

Erickson Domingo
fonte
1

Eu tive o mesmo problema em circunstâncias diferentes.
Eu tinha um elemento simples dentro da etiqueta corporal.
A solução foi:

<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";
}
Pedro
fonte
1

Eu tive o mesmo problema com o meu sistema, removi o código JavaScript da minha página e coloquei-o no corpo pouco antes de fechar a etiqueta do corpo

Jesse Mwangi
fonte
0

Em alguns casos, o ResolveUrl e o ResolveClientUrl funcionam, mas nem sempre, principalmente no caso dos arquivos de script js. O que acontece é que funciona para algumas páginas, mas quando você navega para outras páginas, pode não funcionar devido ao caminho relativo dessa página específica.

Então, finalmente, minha sugestão é sempre fazer uma verificação completa das páginas do seu site para saber se todas as suas referências javascript estão corretas ou não. Abra seu site no Google Chrome -> clique com o botão direito do mouse na página -> clique em Visualizar página de origem -> HTML aparece -> agora clique nos hiperlinks do JS; se estiver funcionando bem, ele deve abrir o arquivo js em outra janela do navegador, caso contrário não será aberto.

mdhameed
fonte
0

Tente escrever seu código de script java fora da tag head, ele definitivamente funcionará. É resolvido quando eu copio e colo meu código Java Script na parte inferior da página. No anterior, ele é colocado na tag HEAD agora, pouco antes de fechar a tag do formulário.

    </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>
Miank
fonte
0

Remova a parte que possui tags de servidor e coloque-a em outro lugar se desejar adicionar controles dinâmicos do código por trás

Removai meu JavaScript da seção principal da página e o adicionei ao corpo da página e o fiz funcionar

vencedor
fonte
0

No meu caso, recebi esse erro porque estava configurando incorretamente o InnerText para uma div com html dentro dela.

Exemplo:

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>
amor ao vivo
fonte
-1

Tags <%= %>não funciona em uma tag com runat="server". Mova seu código com à uma outra tag ( , ...), ou remover a partir do recipiente.<%= %>runat="server"bodyheadrunat="server"

Eduardo Cuomo
fonte