"La collection Controls ne peut pas être modifiée car le contrôle contient des blocs de code"

370

J'essaie de créer un contrôle utilisateur simple qui est un curseur. Lorsque j'ajoute un AjaxToolkit SliderExtender au contrôle utilisateur, j'obtiens cette erreur (* & $ # () @ #:

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

J'ai essayé de mettre un espace réservé dans le contrôle utilisateur et d'ajouter la zone de texte et l'extension de curseur à l'espace réservé par programme et j'obtiens toujours l'erreur.

Voici le code 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>

Quel est le problème?

Daniel P
la source
11
La cause de cette erreur pour moi était d'utiliser le <% = Resolve (); Fonction%> à l'intérieur des balises <script> et <link>. J'ai finalement corrigé cela. Plutôt que de supprimer le code incriminé dans la balise head qui provoque généralement cette erreur. Mettez simplement tout le code incriminé dans une balise <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
Daniel P
stackoverflow.com/questions/4995274/… Contient une explication plus longue de la @Daniel Psuggestion.
lko

Réponses:

498

Commencez par démarrer le bloc de code avec <% # au lieu 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>

Cela modifie le bloc de code d'un bloc de code Response.Write en une expression de liaison de données.
Étant donné que les <%# ... %>expressions de liaison de données ne sont pas des blocs de code, le CLR ne se plaindra pas. Ensuite, dans le code de la page maître, vous ajouteriez ce qui suit:

protected void Page_Load(object sender, EventArgs e)
{
  Page.Header.DataBind();    
}
Jalal El-Shaer
la source
Je ne reçois pas cette erreur, mais j'utilise la notation =. Cependant: j'ai vu mon code échouer avec le problème décrit ci-dessus. Qu'est-ce qui peut causer cela (pourquoi ça marche bien avec moi)?
doekman
3
J'ai semblé commencer à avoir ce problème après être passé à ASP.NET 4. Est-il isolé du nouveau framework?
Corgalore
3
Son résolu lorsque je copie et colle mon code Java Script au bas de la page. Dans le précédent, il est placé dans la balise HEAD.
Miank
1
Il s'agit d'un bug tellement bizarre avec .NET. Pourquoi #au lieu de =. Je ne comprendrai jamais celui-ci, je le fais depuis des années mais j'aimerais savoir POURQUOI!
Mark Pieszak - Trilon.io
1
Des héros sans capes s'ils existent!
Julián
253

J'ai également rencontré ce problème, mais j'ai trouvé une autre solution.

J'ai trouvé qu'envelopper les blocs de code avec un asp: PlaceHolder-tag résout le problème.

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

(Le CMS que j'utilise insère dans la section de tête à partir d'un code derrière lequel m'a empêché d'ajouter des blocs de contrôle personnalisés avec diverses informations comme des méta-balises, etc. c'est donc la seule façon dont cela fonctionne pour moi.)

Jonas Stensved
la source
11
Impressionnant. En tant qu'ancien utilisateur des contrôles Telerik, j'utilisais souvent leur "RadCodeBlock" dans le même but, mais j'étais toujours ennuyé par le fait que je ne connaissais rien d'autre que cela (ou comme d'autres l'ont mentionné, déplacer le code dans un tag fait pour fonctionner côté serveur). Je n'ai jamais su que ces espaces réservés pouvaient contenir du contenu à l'intérieur d'eux. Je vous remercie!
JayC
1
Merci en fait à @JayC, le RadCodeBlock était la seule suggestion sur cette page qui fonctionnait avec le code dont j'ai hérité, pour diverses raisons.
shiser
Cela se produit également avec les contrôles DevExpress enregistrés. J'ai deux applications Web avec du code, une configuration et des pages maîtres presque identiques. Seul celui avec DevExpress nécessite une solution de contournement comme celle-ci. Je pense que c'est quelque chose à voir avec leur gestionnaire HTTP, les assemblys de ressources ou quelque chose comme ça gâcher le pipeline. Nous nous éloignons maintenant des bibliothèques tierces en faveur de JQuery et MVC, ce qui vous permet d'éviter les codes / gestionnaires complexes côté serveur.
Tony Wall
En fait, il suffit de l'envelopper avec <div runat = "server"> <% = (...)%> </div>
Zbigniew Wiadro
5
@Teomanshipahi C'est en fait assez simple - l'utilisation de blocs de code à l'intérieur d'un conteneur signifie que vous ne pouvez plus mettre à jour Controlsce conteneur. Cela exploite essentiellement ce comportement en plaçant le bloc de code dans un conteneur séparé - donc l'erreur n'apparaîtrait que si vous vouliez modifier Controlsle PlaceHolder, plutôt que le contrôle parent. PlaceHolderest un excellent choix pour cela, car il n'a pas de code propre (contrairement à, disons Panelou <div runat="server">). Bien que je l'utilise habituellement dans l'autre sens - mettez les contrôles dont j'ai besoin pour modifier PlaceHolder.
Luaan
55

Je peux confirmer que le déplacement du javascript avec des <% %>balises de la tête vers la balise de formulaire corrige cette erreur

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

ITalez
la source
1
Oui, juste confirmé, la suppression des balises ASP <%%> de la tête corrige cette erreur.
Corgalore
+1, confirmé également. Pour moi, bien que le script problématique soit en dehors des éléments head et form.
user420667
Confirmé. Fonctionne comme un charme pour moi. N'oubliez pas de vérifier les scripts sur votre page principale car c'est celui qui me causait des problèmes et j'ai passé une demi-heure avant de comprendre que ce n'était pas mon aspx: P
Luis Hernández
Oui, cela a fonctionné pour moi aussi, mais pourquoi? La balise <HEAD> dans un fichier maître est destinée uniquement au fichier maître et pas aux fichiers sous-aspx? Je demande parce que j'essaie d'exécuter du code JS dans une page sous-aspx qui réside dans le fichier maître.
Fandango68
31

Placez le javascript sous une balise div.

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

Ça va marcher !!

Anup
la source
5
Ou mieux, utilisez un espace réservé pour qu'aucun code HTML supplémentaire ne soit généré.
Chris Haines
1
Cela fonctionne, bien que Visual Studio indique qu'il viole la norme HTML5 pour imbriquer un <div> dans un <head>.
Adi Inbar
À mon humble avis, pas la meilleure solution si HTML5 ne valide pas, évitez les div dans la headsection.
PreguntonCojoneroCabrón
8

vous pouvez faire la même fonctionnalité si vous utilisez le gestionnaire de scripts dans votre page. vous devez simplement enregistrer le script comme celui-ci

<asp:ScriptManager ID="ScriptManager1" runat="server" LoadScriptsBeforeUI="true"   EnablePageMethods="true">  
<Scripts>
      <asp:ScriptReference Path="~/Styles/javascript/jquery.min.js" />
</Scripts>
</asp:ScriptManager>
Mohan Prajapati
la source
ScriptManagerpas ajouter de scripts dans la section head ?
Kiquenet
5

J'ai eu le même problème dans le contrôle utilisateur. Ma page qui hébergeait le contrôle avait des commentaires dans la balise head, j'ai supprimé ces commentaires, tout a fonctionné par la suite. Certains articles suggèrent également de supprimer les scripts de la tête et de les placer dans le corps.


la source
5

J'ai essayé d'utiliser <%# %>sans succès. Ensuite, j'ai changé Page.Header.DataBind();mon code derrière pourthis.Header.DataBind(); et cela a bien fonctionné.

pseudo
la source
4

Dans mon cas, je l'ai remplacé <%= %>par <%# %>, et ça a marché!

Iori-kyo
la source
3

Gardez le code du script java à l'intérieur de la balise body

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

La technique de liaison de données "<% #" ne fonctionnera pas directement à l'intérieur des balises <link> dans la balise <head>:

<head runat="server">

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

</head>

Le code ci-dessus évaluera

<head>

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

</head>

Au lieu de cela, vous devez faire ce qui suit (notez les deux guillemets doubles à l'intérieur):

<head runat="server">

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

</head>

Et vous obtiendrez le résultat souhaité:

<head>

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

</head>
perryv
la source
2

J'ai eu ce problème, mais pas via l'en-tête. Mon espace réservé était dans le corps. Donc , je l' ai remplacé tous les <%=avec <%#et fait

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

et ça a marché.

bcr
la source
1

Une autre manière consiste à avoir une autre page .aspx agissant comme la page à laquelle vous souhaitez créer un lien.

Voici à quoi ressemble l'en-tête de la Masterpage:

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

Le formulaire .aspx référencé contient votre contenu:

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

Enfin, vous avez besoin de la page .aspx pour indiquer au navigateur que vous envoyez du contenu CSS:

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

J'ai également fait face au même problème. J'ai trouvé les solutions comme suit.

Solution 1: J'ai gardé ma balise de script dans le corps.

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

Désormais, les conflits concernant les balises seront résolus.

Solution 2:

Nous pouvons également résoudre l'une des solutions ci-dessus comme Remplacer le bloc de code par <% # au lieu de <% = Mais le problème est qu'il ne donnera qu'un chemin relatif . Si vous voulez un chemin vraiment absolu, cela ne fonctionnera pas.

La solution 1 fonctionne pour moi. Ensuite, c'est votre choix.

Mihir
la source
1

J'ai eu le même problème, mais cela n'avait rien à voir avec JavaScript. Considérez ce code:

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

Dans cette situation, vous obtiendrez la même erreur même si PlaceHolders n'a aucun bloc de code nuisible, cela se produit en raison du contrôle non serveur hdnTest utilise des blocs de code.

Ajoutez simplement runat = server à hdnTest et le problème est résolu.

homme désespéré
la source
1

J'ai résolu une erreur similaire à celle-ci en mettant l' <script>intérieur contentplaceholderà l'intérieur du <head>au lieu de mettre l' <script>extérieur du dit contentplaceholderà l'intérieur du<head>

Erickson Domingo
la source
1

J'ai eu le même problème avec des circonstances différentes.
J'avais un élément simple à l'intérieur de la balise body.
La solution était:

<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";
}
Peter
la source
1

J'ai eu le même problème avec mon système, j'ai supprimé le code JavaScript de ma page et l'ai mis au corps juste avant de fermer la balise body

Jesse Mwangi
la source
0

Dans certains cas, ResolveUrl et ResolveClientUrl fonctionnent, mais pas toutes les fois en particulier dans le cas de fichiers de script js. Ce qui se passe, c'est que cela fonctionne pour certaines pages, mais lorsque vous accédez à d'autres pages, cela peut ne pas fonctionner en raison du chemin relatif de cette page particulière.

Donc, finalement, ma suggestion est de toujours faire une nouvelle vérification complète des pages de votre site pour savoir si toutes vos références javascript sont correctes ou non. Ouvrez votre site dans Google Chrome -> clic droit sur la page -> cliquez sur afficher la page source -> HTML apparaît -> cliquez maintenant sur vos hyperliens JS; si cela fonctionne bien, il devrait ouvrir le fichier js dans une autre fenêtre du navigateur, sinon il ne s'ouvrira pas.

mdhameed
la source
0

Essayez d'écrire votre code de script java en dehors de la balise head, cela fonctionnera certainement. Il est résolu lorsque je copie et colle mon code de script Java au bas de la page. Dans le précédent, il est placé dans la balise HEAD maintenant juste avant de fermer la balise de formulaire.

    </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
la source
0

Supprimez la partie qui a des balises de serveur et placez-la ailleurs si vous souhaitez ajouter des contrôles dynamiques à partir du code derrière

J'ai supprimé mon JavaScript de la section de tête de la page et l'ai ajouté au corps de la page et l'ai fait fonctionner

Victor
la source
0

Dans mon cas, j'ai eu cette erreur parce que je définissais à tort InnerText sur une div avec html à l'intérieur.

Exemple:

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>
l'amour en direct
la source
-1

Les balises <%= %>ne fonctionnent pas dans une balise avec runat="server". Déplacez votre code avec <%= %>dans runat="server"une autre balise ( body, head, ...), ou retirer runat="server"du contenant.

Eduardo Cuomo
la source