在asp.Net中,控件标记内编写代码会生成编译错误。

6

你好,这真的很奇怪!

但看看下面的asp代码:

    <div runat="server" id="MainDiv">
      <%foreach (string str in new string[]{"First#", "Second#"})
          { %>
            <div id="<%=str.Replace("#","div") %>">
            </div>
        <%} %>
    </div>

现在,如果您将此代码放入任何网页中(不必担心该代码的道德问题,我只是为了展示这个想法而编写它),您将会得到以下错误信息:
编译器错误消息:CS1518:预期类、委托、枚举、接口或结构体。
当然,这个错误与实际问题无关。我搜索了由asp.net生成的代码并找出了以下内容:
     private void @__RenderMainDiv(System.Web.UI.HtmlTextWriter @__w, System.Web.UI.Control parameterContainer)
    {
        @__w.Write("\r\n        ");

        #line 20 "blabla\blabla\Default.aspx"
        foreach (string str in new string[] { "First#", "Second#" })
        {

            #line default
            #line hidden
            @__w.Write("\r\n        <div id=\"");

            #line 22 "blabla\blabla\Default.aspx"
            @__w.Write(str.Replace("#", "div"));


            #line default
            #line hidden
            @__w.Write("\">\r\n        ");
     }

这是从asp页面生成的代码,这是用于渲染我们div (MainDiv) 的方法,我发现缺少了一个花括号“}”,它关闭了方法或(for循环)。
现在问题有三个部分: 1- 首先,您应该拥有一个服务器控件(在我们的情况下是MainDiv),我不确定它是否仅为div标记。 2- 服务器控件内的HTML控件和其中的代码使用双引号(例如< div id="<%=str而不是<div id='<%=str。 3-任何具有块括号的关键字,例如:for{},while{},using{}...等。
现在删除任何部分都将解决问题!!!
这是如何发生的?? 有什么想法吗?
顺便说一句:请帮助我使问题更加明显,因为我找不到最好的词来描述这个问题。
看起来我的问题不够清楚!! 我的问题是:asp.net遵循哪些步骤生成这样错误的代码?? 怎么发生的? 我不想要异常的解决方案,我已经使用单引号解决了它。
5个回答

6

您不能在双引号中嵌套双引号。

<div id="<%=str.Replace("#","div") %>">

它无法确定何时开始或结束,这就是为什么

<div id='<%=str.Replace("#","div") %>'>

如果正确地工作,则会出现以下情况。

否则,它将认为代码是

 <div id="<%=str.Replace("
 ","
 div
 ") %>"
 )

当然这是毫无意义的。

根据我下面的评论更新

添加runat="server"会导致控件被ASP.NET解析,否则它只会直接输出为html。

如果被ASP.NET解析,情况就不同了。说实话,我不确定这里发生了什么精确的内部机制。我所能告诉你的是,如果设置了runat="server"属性,则ASP.NET将对其进行解析,并且它遵循不同的规则。

它将尝试像我上面描述的那样分解内部html。

如果删除了runat="server"属性,则它会作为html输出,因此内联代码将被处理,然后与周围的html一起推出,而不管它是什么,例如双引号。


但是如果您继续使用双引号,并且例如从主div中删除runat="server",问题将得到解决吗?所以问题不在于双引号!!! - Nour
2
不完全是这样。添加runat="server"会导致控件被ASP.NET解析,否则它只是作为HTML直接传递出去。如果它被ASP.NET解析,情况就不同了。老实说,我不确定这里发挥作用的确切内部工作原理。我只能告诉你的是,如果设置了runat="server"属性,那么ASP.NET会解析它,并且它遵循不同的规则。它很可能会尝试像我在答案中描述的那样分解内部HTML。 - Adam
1
@Downvoter - 通常情况下,您应该在评论中说明为什么要给出负评,这样我们才有机会改进回答。 - Adam
@Nour - 我的回答是否已经解释清楚了,还是你需要进一步的解释? - Adam
考虑到第一点,我实际上不同意你的观点。如果你注意到生成的代码: @__w.Write(str.Replace("#", "div")); 你会看到这行是正确的,并且正是应该解析的内容!! - Nour

0

这个对我有用:

<div runat="server" id="MainDiv">
      <%foreach (string str in new string[]{"First#", "Second#"})%>
          <%{%>
          <% string str1 = str.Replace("#","div"); %>
           <div id='<%= str1%>'>123</div> 
           <%}%>
</div>

好的,我知道如何解决这个问题,并且已经解决了它,但我只是好奇这个错误发生的方式是什么? - Nour

0

我不确定您是否能够完全弄清解析器正在做什么,但从最后一行真正的代码可以明显看出,它已经陷入了困境。

@__w.Write("\">\r\n ");

这句话中输出的是 "> 而不仅仅是> - 这是此语句中的最后一个尖括号。

<div id="<%=str.Replace("#","div") %>">

所以,在这一点上,解析器认为它在一个字符串中,但找不到终止符,因此失败了 - 这意味着最后的

<%} %> 从未被解析 - 这就是你遇到问题的原因。

我建议这是因为解析器是按线性方式工作的,只有在发现缺失的字符串终止符时才会发生失败。


0

使用单引号而不是双引号


我的朋友,我已经在问题中提到了解决方案,可你并没有回答我的问题!!! - Nour

0

这很奇怪,很可能是使用该类型语法与 Web 表单有关的问题,但我能够使此代码编译并呈现 div 到页面:

<div runat="server" id="MainDiv">
  <%foreach (string str in new string[] {"First#", "Second#"})
      {%>
        <div id='<%= string.Format("{0}", str.Replace("#","div")) %>'>
            Testing
        </div>
    <%}%>
</div> 

@NourSabouny:问题在于双引号。上述代码编译并呈现了预期的输出。 - James Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接