为啥将 <%= %> 表达式作为服务器控件上的属性值会导致编译错误?
Posted
技术标签:
【中文标题】为啥将 <%= %> 表达式作为服务器控件上的属性值会导致编译错误?【英文标题】:Why will <%= %> expressions as property values on a server-controls lead to a compile errors?为什么将 <%= %> 表达式作为服务器控件上的属性值会导致编译错误? 【发布时间】:2010-09-27 01:53:53 【问题描述】:这个问题是我在尝试回答 another question 时注意到的结果。现在我很想知道为什么<asp:TextBox runat="server" Visible="<%= true %>" />
会导致编译错误,而不是像我预期的那样导致可见的文本框。
从我目前的发现来看,<%= %>
表达式并没有像我一直想的那样被翻译成文字控件。但相反,它在呈现页面时被评估并直接写入 htmlTextWriter。但显然解析器(我不确定这是将 ASP.NET 标记转换为 .NET 代码的部分的正确术语)甚至没有尝试评估 <%= %>
表达式,当它们用作服务器的属性值时控制。它只是将其用作字符串。我猜这就是我收到错误消息的原因:无法从“可见”属性的字符串表示“”创建类型为“System.Boolean”的对象。
如果我改用 runat="server" 并将 <%= %>
与常规 html 标记相结合,如下所示:
<input type="button" id="Button1" visible='<%= true %>' />
然后解析器只是将块在表达式之前和之后分成几部分,然后在 render 方法中将其写入 HtmlTextWriter。像这样的:
__w.Write("<input type=\"button\" id=\"Button1\" visible='");
__w.Write(true);
__w.Write("' />");
作为我注意到的最后一件事......当我尝试使用<%# %>
+ Control.DataBind() 时,我得到了我所期望的。当控件是数据绑定时,它连接要使用的表达式,但与 表达式不同,生成的代码实际上计算 <%# %>
表达式的内容。解析器最终生成以下内容:
[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;
,它是<%# %>
表达式的结果。
所以我的问题是.. 为什么第一个示例中的表达式只是被视为一个字符串,而不是被评估为“真”。其他两个示例的表达式有些相似,它们产生了我预期的代码。
这只是一个错误(我怀疑这不是当前版本的 ASP.NET 的新问题),还是有充分的理由不允许我们像那样使用<%= %>
?
【问题讨论】:
【参考方案1】:这个:
<asp:Button runat="server" id="Button1" visible='<%= true %>' />
不评价这个:
<asp:Button runat="server" id="Button1" visible='true' />
直接输出到响应流,asp 标记不是响应流的一部分。假设 运算符对 asp 标记执行任何类型的预处理是错误的。
顺便说一句,考虑 和 运算符的 ASP.NET 生命周期会有所帮助。
的语义更类似于为对象赋值。在 ASP.NET 生命周期中, 运算符在页面将第一个字节写入响应缓冲区之前进行评估。
与 Response.Write 的含义相同。我们需要首先执行所有数据绑定和表单处理,并在 ASP.NET 生命周期的最后阶段将 HTML 输出到响应缓冲区。
【讨论】:
谢谢,很有道理,它符合我在 Reflector 中看到的内容。我想我希望“Response.Write”效果只是我如何使用它的结果,而不是它的工作方式。 +1 必须阅读此答案两次才能抓住重点:直接输出到响应流,并且 asp 标记不是响应流的一部分 aka,@987654323 @ 不会出现在<asp:Button visible
属性中,而是出现在不相关的某个地方!
您还必须在 PageLoad 方法中调用 Button1.DataBind()
或者如果它更容易(很多控件需要 DataBind )调用 Me.DataBind() 来绑定属于页面的所有控件。
想知道为什么它没有将属性="" 转换为为 webform/控件生成的代码中的 control.Attributes["attribute"]=value以上是关于为啥将 <%= %> 表达式作为服务器控件上的属性值会导致编译错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥不能使用 null 作为 Dictionary<bool?, string> 的键?
C# 中的错误:“表达式树可能不包含基本访问” - 为啥不呢?