为什么将<%=%>expression式作为服务器控件上的属性值导致编译错误?

这个问题是我在回答另一个问题时注意到的结果。 现在我很好奇,知道为什么<asp:TextBox runat="server" Visible="<%= true %>" />导致编译错误,而不是一个可见的TextBox,因为我会有所期待。

从我迄今为止发现的情况来看, <%= %>expression式并没有被转换成文字控制,正如我一直以为的那样。 但是,当页面呈现时,它会被评估并直接写入HtmlTextWriter。 但显然,parsing器(我不确定这是正确的术语,是将ASP.NET标记翻译为.NET代码的部分)甚至不试图评估<%= %>expression式,当它们被用作属性值用于服务器控件。 它只是用它作为一个string。 我猜是为什么我得到的错误信息: 不能创build一个types'System.Boolean'从它的string表示'<%= true%>的'可见'属性的对象

如果我改为使用runat =“server”,并将<%= %>与常规的html标记相结合,如下所示:

 <input type="button" id="Button1" visible='<%= true %>' /> 

然后,parsing器只是在expression式之前和之后分割块,然后将其写入呈现方法中的HtmlTextWriter。 像这样的东西:

  __w.Write("<input type=\"button\" id=\"Button1\" visible='"); __w.Write(true); __w.Write("' />"); 

作为我注意到的最后一件事…当我尝试使用<%# %> + Control.DataBind(),然后我得到我所期望的。 当控件是数据绑定时,它会挂钩使用的expression式,但与<%=%>expression式不同,生成的代码实际上会评估<%# %>expression式的内容。 parsing器结束生成以下内容:

 [DebuggerNonUserCode] private Button __BuildControldataboundButton() { Button button = new Button(); base.databoundButton = button; button.ApplyStyleSheetSkin(this); button.ID = "databoundButton"; button.DataBinding += new EventHandler(this.__DataBindingdataboundButton); return button; } public void __DataBindingdataboundButton(object sender, EventArgs e) { Button button = (Button) sender; Page bindingContainer = (Page) button.BindingContainer; button.Visible = true; } 

从:

 <asp:Button ID="databoundButton" Visible='<%# true %>' runat="server" /> 

注意button.Visible = true; 这是<%# %>expression式的结果。

所以我的问题是…为什么在第一个例子中的expression只是作为一个string对待,而不是被评估为“真”。 这两个expression式对于另外两个例子有点类似,并且它们产生了我期望的代码。

这只是一个错误(我怀疑,因为它不是一个新的问题与当前版本的ASP.NET),还是有一个很好的理由,为什么我们不被允许使用这样的<%= %>

这个:

 <asp:Button runat="server" id="Button1" visible='<%= true %>' /> 

不要评估这个:

 <asp:Button runat="server" id="Button1" visible='true' /> 

<%=%>直接输出到响应stream,而asp标记不是响应stream的一部分。 假设<%=%>运算符正在对asp标记执行任何types的预处理是错误的。


另外,考虑到<%#%>和<%=%>运算符,可以帮助您考虑ASP.NET生命周期。

  • <%#%>具有与将对象赋值相同的语义。 在ASP.NET生命周期中,在页面将第一个字节写入响应缓冲区之前,对<%#%>运算符进行求值。

  • <%=%>的含义与Response.Write相同。 我们需要首先执行我们所有的数据绑定和表单处理,并在ASP.NET生命周期的最后将HTML输出到响应缓冲区。