“无法修改控件集合,因为控件包含代码块”


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>标记中。
丹尼尔·P 2009年

stackoverflow.com/questions/4995274/…包含对该@Daniel P建议的较长解释。
lko 2012年

Answers:


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

3
切换到ASP.NET 4后,我似乎开始出现此问题。它是否与新框架隔离?
Corgalore 2011年

3
当我将Java Script代码复制并粘贴到页面底部时,它已解决。在前面将其放置在HEAD标签中。
Miank 2014年

1
.NET真是一个奇怪的错误。为什么要#代替=。我永远都不会理解这个,已经做了很多年了,但是希望我知道为什么!
Mark Pieszak-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 '02

1
实际上,感谢@JayC,由于各种原因,RadCodeBlock是此页面上唯一与我继承的代码一起使用的建议。
shiser 2012年

在注册DevExpress控件时也会发生这种情况。我有两个具有几乎相同的代码,配置和母版页的Web应用程序。只有具有DevExpress的开发人员需要这种解决方法。我认为这与他们的HTTP处理程序,资源程序集或类似的东西打乱了管道。现在,我们不再使用第三方库,而是使用JQuery和MVC,这使您可以避免复杂的服务器端代码/处理程序。
托尼·沃尔

实际上,用<div runat =“ server”> <%=(...)%> </ div>包裹起来就足够了
Zbigniew Wiadro 2013年

5
@Teomanshipahi实际上非常简单-在容器内使用代码块意味着您无法再更新Controls该容器。这基本上是利用通过将这种行为的代码块在一个单独的容器-这样的错误只会显示,如果你想修改ControlsPlaceHolder,而不是家长控制。PlaceHolder这样做是个不错的选择,因为它没有自己的任何代码(不同于,说Panel<div runat="server">)。尽管我通常以其他方式使用它-将需要修改的控件放入其中PlaceHolder
a安2015年

55

我可以确认将javascript与 <% %>标签从头部移动到表单标签可以解决此错误

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


1
是的,刚刚确认,从头部移除ASP标签<%%>可以修复此错误。
Corgalore 2011年

+1,也被确认。对我而言,尽管有问题的脚本不在头和形式元素之列。
user420667

已确认。对我来说就像一个魅力。只是不要忘记检查您母版页上的脚本,因为这是给我造成麻烦的脚本,我花了半个小时才弄清楚这不是我的aspx:P
LuisHernández2014年

是的,这对我也有用,但是为什么呢?主文件中的<HEAD>标记是否仅用于主文件,而没有sub-aspx文件?我问是因为我试图在驻留在主文件中的sub-aspx页面中运行JS代码。
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表示在<head>内嵌套<div>违反了HTML5标准,但这种方法有效。
Adi Inbar,2015年

恕我直言,如果HTML5无法验证,则不是最佳解决方案,请避免在本节中使用divhead
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 '17

5

我在用户控件中遇到了同样的问题。我托管该控件的页面的head标签中有注释,我删除了这些注释,之后一切正常。一些帖子还建议从头部删除脚本并将其放置在体内。


5

我尝试使用<%# %>没有成功。然后,我将Page.Header.DataBind();代码更改为this.Header.DataBind();,并且运行良好。


4

就我而言,我已替换<%= %><%# %>,并且有效!



2

“ <%#”数据绑定技术将不能直接在<head>标记的<link>标记内使用:

<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

我遇到了这个问题,但是没有通过Header。我的占位符在体内。所以我全部换成了<%=<%#和做

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 = server添加到hdnTest,即可解决问题。



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";
}


0

在某些情况下,ResolveUrl和ResolveClientUrl可以工作,但并非始终都有效,特别是在js脚本文件的情况下。发生的事情是它对某些页面有效,但是当您导航到某些其他页面时,由于该特定页面的相对路径,它可能无法正常工作。

因此,最后,我的建议是始终对您的网站页面进行完整的重新检查,以检查您所有的JavaScript引用是否正确。在Google Chrome中打开您的网站->右键单击页面->单击查看源页面->出现HTML->现在单击您的JS超链接;如果工作正常,则应在另一个浏览器窗口中打开js文件,否则将无法打开。


0

尝试在head标记之外编写Java脚本代码,它肯定会起作用。当我将Java Script代码复制并粘贴到页面底部时,此问题已解决。在以前的版本中,现在在关闭form标签之前将其放置在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设置为其中包含html的div。

例:

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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.