„Nie można zmodyfikować kolekcji formantów, ponieważ formant zawiera bloki kodu”

370

Próbuję utworzyć prostą kontrolę użytkownika, która jest suwakiem. Gdy dodam AjaxToolkit SliderExtender do kontroli użytkownika, otrzymuję ten błąd (* i $ # () @ #:

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

Próbowałem umieścić symbol zastępczy w formancie użytkownika i programowo dodać pole tekstowe i przedłużacz suwaka do symbolu zastępczego i nadal pojawia się błąd.

Oto prosty kod:

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

Jaki jest problem?

Daniel P.
źródło
11
Przyczyną tego błędu był dla mnie użycie <% = Resolve (); %> wewnątrz tagów <script> i <link>. W końcu to naprawiłem. Zamiast usuwać kod obrażający z tagu head, który zwykle powoduje ten błąd. Po prostu umieść cały szkodliwy kod w znaczniku <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
Daniel P
stackoverflow.com/questions/4995274/... Zawiera dłuższe wyjaśnienie @Daniel Psugestii.
lko

Odpowiedzi:

498

Najpierw uruchom blok kodu za pomocą <% # zamiast <% =:

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

Spowoduje to zmianę bloku kodu z bloku kodu Response.Write na wyrażenie wiązania danych.
Ponieważ <%# ... %>wyrażenia wiążące dane nie są blokami kodu, CLR nie będzie narzekać. Następnie w kodzie strony wzorcowej dodaj:

protected void Page_Load(object sender, EventArgs e)
{
  Page.Header.DataBind();    
}
Jalal El-Shaer
źródło
Nie otrzymuję tego błędu, ale używam notacji =. Jednak: widziałem, że mój kod nie działa z wyżej opisanym problemem. Co może być przyczyną (dlaczego działa ze mną dobrze)?
doekman
3
Wydawało mi się, że ten problem zacząłem po przejściu na ASP.NET 4. Czy jest on odizolowany od nowej struktury?
Corgalore,
3
Rozwiązano problem, gdy kopiuję i wklejam mój kod Java Script na dole strony. W poprzednim został umieszczony w znaczniku HEAD.
Miank
1
To taki dziwny błąd w .NET. Dlaczego #zamiast =. Nigdy tego nie zrozumiem, robiłem to od lat, ale chciałbym wiedzieć DLACZEGO!
Mark Pieszak - Trilon.io
1
Bohaterowie bez peleryny, jeśli istnieją!
Julián,
253

Właśnie natrafiłem na ten problem, ale znalazłem inne rozwiązanie.

Odkryłem, że owijanie bloków kodu asp: Tag PlaceHolder rozwiązuje problem.

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

(CMS, którego używam, to wstawianie do nagłówka z jakiegoś kodu, za którym nie mogłem dodawać niestandardowych bloków kontrolnych z różnymi informacjami, takimi jak metatagi itp., Więc jest to jedyny sposób, który działa dla mnie.)

Jonas Stensved
źródło
11
Niesamowite. Jako były użytkownik kontrolek Telerik często używałem ich „RadCodeBlock” w tym samym celu, ale zawsze byłem zirytowany faktem, że nie wiedziałem nic poza tym (lub jak wspomnieli inni, przenoszenie kodu do tag stworzony do uruchamiania po stronie serwera). Nigdy nie wiedziałem, że te symbole zastępcze mogą zawierać treści. Dziękuję Ci!
JayC
1
Dziękuję właściwie @JayC, RadCodeBlock był jedyną sugestią na tej stronie, która działała z odziedziczonym przeze mnie kodem, z różnych powodów.
shiser
Dzieje się tak również z zarejestrowanymi kontrolami DevExpress. Mam dwie aplikacje internetowe z prawie identycznym kodem, konfiguracją i stronami wzorcowymi. Tylko ten z DevExpress wymaga takiego obejścia. Myślę, że ma to coś wspólnego z ich obsługą HTTP, zestawami zasobów lub czymś takim, co psuje potok. Odchodzimy teraz od bibliotek stron trzecich na rzecz JQuery i MVC, co pozwala uniknąć skomplikowanego kodu / procedur obsługi po stronie serwera.
Tony Wall
W rzeczywistości wystarczy owinąć go <div runat = "server"> <% = (...)%> </div>
Zbigniew Wiadro
5
@Teomanshipahi W rzeczywistości jest to dość proste - użycie bloków kodu w kontenerze oznacza, że ​​nie można już aktualizować Controlstego kontenera. To w zasadzie wykorzystuje ten problem poprzez wprowadzenie blok kodu w osobnym pojemniku - więc błąd pokaże tylko jeśli chcesz zmodyfikować Controlsz PlaceHolder, zamiast sterowania nadrzędnego. PlaceHolderjest do tego doskonałym wyborem, ponieważ nie ma własnego kodu (w przeciwieństwie do powiedz Panellub <div runat="server">). Chociaż zwykle używam go na odwrót - umieść elementy sterujące, które muszę zmodyfikować PlaceHolder.
Luaan
55

Mogę potwierdzić, że przeniesienie javascript z <% %>tagami z nagłówka do tagu formularza naprawia ten błąd

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

ITalez
źródło
1
Tak, właśnie potwierdzone, usunięcie tagów ASP <%%> z głowy naprawia ten błąd.
Corgalore,
+1, również potwierdzone. Dla mnie jednak problematyczny skrypt znajdował się poza główką i elementami formularza.
user420667
Potwierdzony. Dla mnie działa jak urok. Tylko nie zapomnij sprawdzić skryptów na twojej stronie wzorcowej, ponieważ to on sprawiał mi kłopoty i spędziłem pół godziny, zanim odkryłem, że to nie mój aspx: P
Luis Hernández
Tak, to też działało dla mnie, ale dlaczego? Czy znacznik <HEAD> w pliku głównym ma być przeznaczony wyłącznie dla pliku głównego i nie ma plików sub-aspx? Pytam, ponieważ próbuję uruchomić kod JS na stronie sub-aspx, która znajduje się w pliku głównym.
Fandango68,
31

Umieść javascript pod znacznikiem div.

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

To zadziała !!

Anup
źródło
5
Lub lepiej, użyj symbolu zastępczego, aby nie generować dodatkowego kodu HTML.
Chris Haines,
1
Działa to, chociaż Visual Studio twierdzi, że naruszanie standardu HTML5 polega na zagnieżdżaniu <div> w <head>.
Adi Inbar,
IMHO, nie najlepsze rozwiązanie, jeśli HTML5 nie sprawdza się, unikaj div w headsekcji.
PreguntonCojoneroCabrón
8

możesz wykonać tę samą funkcjonalność, jeśli używasz menedżera skryptów na swojej stronie. musisz tylko zarejestrować skrypt w ten sposób

<asp:ScriptManager ID="ScriptManager1" runat="server" LoadScriptsBeforeUI="true"   EnablePageMethods="true">  
<Scripts>
      <asp:ScriptReference Path="~/Styles/javascript/jquery.min.js" />
</Scripts>
</asp:ScriptManager>
Mohan Prajapati
źródło
ScriptManagernie dodawać skryptów w sekcji head ?
Kiquenet,
5

Miałem ten sam problem z kontrolą użytkownika. Moja strona, na której znajdowała się kontrola, miała komentarze w tagu head, usunąłem te komentarze, wszystko działało później. Niektóre posty sugerują również usunięcie skryptów z głowy i umieszczenie ich w ciele.


źródło
5

Próbowałem używać <%# %>bez powodzenia. Potem zmieniłem Page.Header.DataBind();kod na this.Header.DataBind();i działało dobrze.

Nacięcie
źródło
4

W moim przypadku, zastąpiły <%= %>z <%# %>, i to działa!

Iori-kyo
źródło
3

Trzymaj kod skryptu Java w tagu body

<body> 
   <script type="text/javascript">
   </script>
</body>
Vikash Pathak
źródło
2

Technika wiązania danych „<% #” nie będzie działać bezpośrednio w znacznikach <link> w znaczniku <head>:

<head runat="server">

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

</head>

Powyższy kod zostanie oceniony jako

<head>

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

</head>

Zamiast tego należy wykonać następujące czynności (zwróć uwagę na dwa podwójne cudzysłowy w środku):

<head runat="server">

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

</head>

I uzyskasz pożądany wynik:

<head>

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

</head>
perryv
źródło
2

Miałem ten problem, ale nie przez nagłówek. Mój symbol zastępczy był w ciele. Więc wymieniłem wszystkie <%=z <%#i zrobił

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

i zadziałało.

bcr
źródło
1

Alternatywnym sposobem jest, aby inna strona .aspx działała jako strona, do której chcesz utworzyć link.

Tak wygląda nagłówek strony głównej:

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

Przywoływany formularz .aspx zawiera treść:

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

Na koniec potrzebujesz strony .aspx, aby poinformować przeglądarkę, że wysyłasz zawartość CSS:

protected void Page_Load(object sender, EventArgs e)
{
    Response.ContentType = "text/css";
}
Hugo
źródło
1

Zetknąłem się również z tym samym problemem. Znalazłem następujące rozwiązania.

Rozwiązanie 1: Trzymałem znacznik skryptu w ciele.

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

Teraz konflikty dotyczące tagów zostaną rozwiązane.

Rozwiązanie 2:

Możemy również rozwiązać to jedno z powyższych rozwiązań, takie jak Zastąp blok kodu <% # zamiast <% = Ale problemem jest to, że da tylko względną ścieżkę . Jeśli chcesz naprawdę absolutną ścieżkę, to nie zadziała.

Rozwiązanie 1 działa dla mnie. Następny jest twój wybór.

Mihir
źródło
1

Miałem ten sam problem, ale nie miało to nic wspólnego z JavaScript. Rozważ ten kod:

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

W tej sytuacji pojawi się ten sam błąd, mimo że PlaceHolders nie ma żadnych szkodliwych bloków kodu, dzieje się tak z powodu kontroli innej niż serwer hdnTest używa bloków kodu.

Po prostu dodaj runat = server do hdnTest, a problem zostanie rozwiązany.

zdesperowany człowiek
źródło
1

Rozwiązałem błąd podobny do tego, wkładając <script>wnętrze do contentplaceholderśrodka <head>zamiast wkładając to, <script>co powiedziane do contentplaceholderśrodka<head>

Erickson Domingo
źródło
1

Miałem ten sam problem z różnymi okolicznościami.
Miałem prosty element wewnątrz znacznika body.
Rozwiązaniem było:

<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";
}
Piotr
źródło
1

Miałem ten sam problem z systemem, usunąłem kod JavaScript ze strony i umieściłem go w treści tuż przed zamknięciem tagu treści

Jesse Mwangi
źródło
0

W niektórych przypadkach ResolveUrl i ResolveClientUrl działa, ale nie zawsze, szczególnie w przypadku plików skryptowych js. To, co się dzieje, działa na niektórych stronach, ale po przejściu do niektórych innych stron może nie działać z powodu względnej ścieżki tej konkretnej strony.

Wreszcie moją propozycją jest zawsze pełne sprawdzenie stron witryny pod kątem tego, czy wszystkie odwołania do javascript są w porządku, czy nie. Otwórz witrynę w Google Chrome -> kliknij stronę prawym przyciskiem myszy -> kliknij wyświetl stronę źródłową -> pojawi się HTML -> teraz kliknij hiperłącza JS; jeśli działa poprawnie, powinien otworzyć plik js w innym oknie przeglądarki, w przeciwnym razie nie zostanie otwarty.

mdhameed
źródło
0

Spróbuj napisać kod skryptu Java poza tagiem head, który na pewno zadziała. Rozwiązano go, gdy kopiowałem i wklejałem mój kod Java Script na dole strony. W poprzednim miejscu umieszczano go w znaczniku HEAD tuż przed zamknięciem znacznika formularza.

    </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
źródło
0

Usuń część, która ma znaczniki serwera i umieść ją w innym miejscu, jeśli chcesz dodać dynamiczne elementy sterujące z kodu z tyłu

Usunąłem JavaScript z sekcji nagłówka strony, dodałem go do treści strony i uruchomiłem

zwycięzca
źródło
0

W moim przypadku dostałem ten błąd, ponieważ źle ustawiłem InnerText na div z html w nim.

Przykład:

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>
żywa miłość
źródło
-1

Tagi <%= %>nie działają w tagach z runat="server". Przenieś swój kod z <%= %>na runat="server"do innego znacznika ( body, head...), lub wyjąć runat="server"z pojemnika.

Eduardo Cuomo
źródło