"Колекцію елементів керування неможливо змінити, оскільки контроль містить кодові блоки"


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>. Я нарешті це виправив. Замість того, щоб видаляти код-порушення, який міститься в тезі заголовка, що зазвичай викликає цю помилку. Просто покладіть увесь код, який порушує право, у тег <asp: ContentPlaceHolder> </ asp: ContentPlaceHolder>.
Даніель П

stackoverflow.com/questions/4995274/… Містить більш тривале пояснення для @Daniel Pпропозиції.
lko

Відповіді:


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. Це ізольовано до нового фреймворку?
Коргалоре

3
Її вирішено, коли я копіюю та вставляю код Java Script у нижній частині сторінки. У попередньому його розміщують у тезі HEAD.
Miank

1
Це така химерна помилка з .NET. Чому #замість цього =. Я ніколи цього не зрозумію, роблю це роками, але хочу, щоб я знала, ЧОМУ!
Марк Пешак - Trilon.io

1
Герої без накидок, якщо вони є!
Джуліан

253

Я просто зіткнувся з цією проблемою, але знайшов інше рішення.

Я виявив, що обгортання кодових блоків за допомогою asp: PlaceHolder-tag вирішує проблему.

<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, що дозволяє уникнути складних кодів / обробників на стороні сервера.
Tony Wall

Насправді достатньо обернути це на <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/


1
Так, щойно підтверджено, видалення тегів ASP <%%> з голови виправляє цю помилку.
Коргалоре

+1, також підтверджено. Для мене, хоча проблемний сценарій знаходився поза елементами голови та форми.
user420667

Підтверджено. Діє як шарм для мене. Тільки не забудьте перевірити сценарії на своїй головній сторінці, оскільки це був той, хто викликав у мене неприємності, і я витратив, як півгодини, перш ніж з'ясувати, що це не моя осінь: P
Луїс Ернандес

Так, це працювало і для мене, але чому? Чи тег <HEAD> у головному файлі призначений виключно для головного файлу та немає файлів sub-aspx? Я запитую, тому що я намагаюся запустити JS-код на сторінці sub-aspx, що знаходиться в головному файлі.
Fandango68

31

Розмістіть javascript під тегом div.

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

Це буде працювати !!


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не додавати сценарії в головний розділ ?
Кікенет

5

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


5

Я намагався використовувати, <%# %>не маючи успіху. Потім я змінив Page.Header.DataBind();свій код позаду, this.Header.DataBind();і він працював чудово.




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>

2

У мене була ця проблема, але не через заголовок. Мій заповнювач був у тілі. Тому я замінив все <%=з <%#і зробив

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

і це спрацювало.


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 для мене працює. Далі - ваш вибір.


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 = сервер до 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 зі своєї сторінки і поставив його на корпусі безпосередньо перед закриттям тегу body


0

У деяких випадках ResolveUrl і ResolveClientUrl працює, але не завжди, особливо у випадку файлів скриптів js. Що трапляється, це працює на деяких сторінках, але коли ви переходите до інших сторінок, це може не працювати через відносний шлях до цієї сторінки.

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


0

Спробуйте написати свій код сценарію Java поза тегом head, він обов'язково спрацює. Він вирішений, коли я копіюю та вставляю код Java Script у нижній частині сторінки. У попередньому його розміщують у тезі 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>

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"з контейнера.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.