«Коллекция элементов управления не может быть изменена, поскольку элемент управления содержит блоки кода»

370

Я пытаюсь создать простой пользовательский элемент управления, который является слайдером. Когда я добавляю AjaxToolkit SliderExtender в пользовательский элемент управления, я получаю эту ошибку (* & $ # () @ #:

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

Я попытался поместить заполнитель в пользовательский элемент управления и добавить текстовое поле и расширитель ползунка программно, и я все еще получаю сообщение об ошибке.

Вот простой код:

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

В чем проблема?

Даниэль П
источник
11
Для меня причиной этой ошибки было использование <% = Resolve (); Функция%> внутри тегов <script> и <link>. Я наконец исправил это. Вместо удаления нарушающего кода в теге head, который обычно вызывает эту ошибку. Просто поместите весь нарушающий код в тег <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
Даниэль П
stackoverflow.com/questions/4995274/… Содержит более длинное объяснение для @Daniel Pпредложения.
2012 г.

Ответы:

498

Сначала запустите блок кода с <% # вместо <% =:

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

Это изменяет блок кода с блока кода Response.Write на выражение привязки данных.
Поскольку <%# ... %>выражения привязки данных не являются блоками кода, CLR не будет жаловаться. Затем в коде главной страницы вы добавите следующее:

protected void Page_Load(object sender, EventArgs e)
{
  Page.Header.DataBind();    
}
Джалал эш-Шаер
источник
Я не получаю эту ошибку, но я использую обозначение =. Тем не менее: я видел мой код сбоя с вышеописанной проблемой. Что может вызвать это (почему это работает хорошо со мной)?
doekman
3
Кажется, у меня возникла эта проблема после перехода на ASP.NET 4. Изолирован ли он от нового фреймворка?
Corgalore
3
Это решается, когда я копирую и вставляю свой код Java Script в конец страницы. В предыдущем он помещен в тег HEAD.
Miank
1
Это такая странная ошибка с .NET. Почему #вместо =. Я никогда не пойму этого, делаю это годами, но хотелось бы знать ПОЧЕМУ!
Марк Писак - Trilon.io
1
Герои без накидок, если они существуют!
Julián
253

Я просто столкнулся с этой проблемой, но нашел другое решение.

Я обнаружил, что обертывание блоков кода тегом asp: PlaceHolder решает проблему.

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

(CMS, которую я использую, вставляет в раздел заголовка какой-то код, который ограничивает меня от добавления пользовательских блоков управления с различной информацией, такой как мета-теги и т. Д., Так что это единственный способ, которым он работает для меня.)

Джонас Стенсвед
источник
11
Потрясающие. Будучи бывшим пользователем элементов управления Telerik, я часто использовал их «RadCodeBlock» для той же цели, но меня всегда раздражал тот факт, что я ничего не знал, кроме этого (или, как уже упоминалось, перемещение кода в тег сделан для запуска на стороне сервера). Я никогда не знал, что эти заполнители могут иметь контент внутри них. Спасибо!
JayC
1
На самом деле, спасибо @JayC, RadCodeBlock был единственным предложением на этой странице, которое работало с унаследованным кодом по разным причинам.
Shiser
Это также происходит с зарегистрированными элементами управления DevExpress. У меня есть два веб-приложения с почти одинаковым кодом, конфигурацией и мастер-страницами. Только тот, который с DevExpress требует обходного пути, как это. Я думаю, что это как-то связано с их обработчиком HTTP, сборками ресурсов или чем-то в этом роде. Сейчас мы переходим от сторонних библиотек к JQuery и MVC, что позволяет вам избегать сложных серверных кодов / обработчиков.
Тони Уолл
На самом деле этого достаточно, чтобы обернуть его в <div runat = "server"> <% = (...)%> </ div>
Zbigniew Wiadro
5
@Teomanshipahi На самом деле все довольно просто - использование блоков кода внутри контейнера означает, что вы больше не можете обновлять Controlsэтот контейнер. Это в основном использует это поведение, помещая блок кода в отдельном контейнере - так ошибка будет отображаться только , если вы хотите изменить Controlsиз PlaceHolder, а не родительского контроля. PlaceHolderэто отличный выбор для этого, потому что у него нет собственного кода (в отличие, скажем, Panelили <div runat="server">). Хотя я обычно использую его наоборот - вставьте элементы управления, которые мне нужно изменить PlaceHolder.
Луаан
55

Я могу подтвердить, что перемещение JavaScript с <% %>тегами из головы в тег формы исправляет эту ошибку

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

ITalez
источник
1
Да, только что подтвердил: удаление тегов ASP <%%> из заголовка исправляет эту ошибку.
Corgalore
+1, подтверждено также. Хотя для меня проблемный сценарий находился вне головы и элементов формы.
user420667 15.02.13
Подтверждено. Работает как шарм для меня. Только не забудьте проверить сценарии на своей главной странице, так как именно это доставляло мне неприятности, и я потратил около получаса, чтобы понять, что это не моя задница: P
Луис Эрнандес,
Да, это сработало и для меня, но почему? Предназначен ли тег <HEAD> в мастер-файле исключительно для мастер-файла, а не для файлов sub-aspx? Я спрашиваю, потому что я пытаюсь запустить код JS на странице ниже aspx, которая находится в мастер-файле.
Fandango68
31

Поместите JavaScript под тегом div.

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

Это сработает !!

Anup
источник
5
Или лучше использовать заполнитель, чтобы не выводить лишний HTML-код.
Крис Хейнс
1
Это работает, хотя Visual Studio говорит, что нарушает стандарт HTML5 для вложения <div> в <head>.
Ади Инбар
ИМХО, не лучшее решение, если HTML5 не проверяет, избегайте div в headразделе.
PreguntonCojoneroCabrón
8

Вы можете сделать ту же функциональность, если вы используете менеджер скриптов на своей странице. Вы должны просто зарегистрировать скрипт, как это

<asp:ScriptManager ID="ScriptManager1" runat="server" LoadScriptsBeforeUI="true"   EnablePageMethods="true">  
<Scripts>
      <asp:ScriptReference Path="~/Styles/javascript/jquery.min.js" />
</Scripts>
</asp:ScriptManager>
Мохан Праджапати
источник
ScriptManagerне добавлять скрипты в головной раздел ?
Kiquenet
5

У меня была такая же проблема в пользовательском контроле. На моей странице, на которой размещался элемент управления, были комментарии в теге head, я удалил эти комментарии, потом все заработало. Некоторые посты также предлагают удалить скрипты из головы и поместить их в тело.


источник
5

Я пытался использовать <%# %>безуспешно. Затем я изменил Page.Header.DataBind();свой код на, this.Header.DataBind();и он работал нормально.

Ник
источник
4

В моем случае я заменил <%= %>на <%# %>, и это сработало!

Иори-кё
источник
3

Держите код java-скрипта внутри тега body

<body> 
   <script type="text/javascript">
   </script>
</body>
Викаш Патхак
источник
2

Метод привязки данных <% # не будет работать напрямую внутри тегов <link> в теге <head>:

<head runat="server">

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

</head>

Приведенный выше код будет оцениваться как

<head>

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

</head>

Вместо этого вы должны сделать следующее (обратите внимание на две двойные кавычки внутри):

<head runat="server">

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

</head>

И вы получите желаемый результат:

<head>

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

</head>
perryv
источник
2

У меня была эта проблема, но не через Заголовок. Мой заполнитель был в теле. Поэтому я заменил все <%=с <%#и сделал

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

и это сработало.

BCR
источник
1

Альтернативный способ - заставить другую страницу .aspx выступать в качестве страницы, на которую вы хотите сослаться.

Вот как выглядит заголовок главной страницы:

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

Ссылочная форма .aspx содержит ваш контент:

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

Наконец, вам нужна страница .aspx, чтобы сообщить браузеру, что вы отправляете контент CSS:

protected void Page_Load(object sender, EventArgs e)
{
    Response.ContentType = "text/css";
}
Хьюго
источник
1

Я также столкнулся с той же проблемой. Я нашел решения, как следующие.

Решение 1: я сохранил свой скрипт тег в теле.

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

Теперь конфликты относительно тегов разрешатся.

Решение 2:

Мы также можем решить это одно из приведенных выше решений, таких как Заменить блок кода на <% # вместо <% =. Но проблема в том, что он даст только относительный путь . Если вы хотите действительно абсолютный путь, он не сработает.

Решение 1 работает для меня. Далее ваш выбор.

Mihir
источник
1

У меня была та же проблема, но она не имела ничего общего с JavaScript. Рассмотрим этот код:

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

В этой ситуации вы получите ту же ошибку, даже если у PlaceHolders нет вредоносных блоков кода, это происходит из-за несерверного управления hdnTest использует блоки кода.

Просто добавьте runat = server в hdnTest, и проблема решена.

отчаянный человек
источник
1

Я решил ошибку, похожую на эту, поместив <script>внутреннюю часть contentplaceholderвнутрь, <head>вместо того, чтобы поместить <script>внешнюю часть contentplaceholderвнутри<head>

Эриксон Доминго
источник
1

У меня была такая же проблема с разными обстоятельствами.
У меня был простой элемент внутри тега body.
Решение было:

<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

У меня была такая же проблема с моей системой, я удалил код JavaScript со своей страницы и поместил его в тело непосредственно перед закрытием тега тела

Джесси Мванги
источник
0

В некоторых случаях ResolveUrl и ResolveClientUrl работают, но не всегда, особенно в случае файлов сценариев js. Что происходит, это работает для некоторых страниц, но когда вы переходите на другие страницы, это может не работать из-за относительного пути к этой конкретной странице.

Итак, наконец, я предлагаю всегда перепроверять страницы вашего сайта, чтобы убедиться, что все ваши ссылки на JavaScript хороши или нет. Откройте свой сайт в Google Chrome -> щелкните правой кнопкой мыши на странице -> нажмите кнопку просмотра исходной страницы -> появится HTML -> теперь нажмите на гиперссылки JS; если он работает нормально, он должен открыть файл js в другом окне браузера, иначе он не откроется.

mdhameed
источник
0

Попробуйте написать код Java-сценария вне тега head, он определенно будет работать. Он разрешается, когда я копирую и вставляю свой код Java-сценария в конец страницы. В предыдущем он помещается в тег HEAD, прямо перед закрытием тега формы.

    </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
источник
0

Удалите часть, которая имеет серверные теги, и поместите ее где-нибудь еще, если вы хотите добавить динамические элементы управления из кода позади

Я удалил свой JavaScript из заголовка раздела страницы и добавил его в тело страницы, и он заработал

Виктор
источник
0

В моем случае я получил эту ошибку, потому что я неправильно установил InnerText в div с html внутри.

Пример:

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

Теги <%= %>не работают в тег с runat="server". Переместите код <%= %>в runat="server"к другому тегу ( body, head, ...), или удалить runat="server"из контейнера.

Эдуардо Куомо
источник