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

Tom*_*len 51 asp.net controls

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

从我迄今发现的内容来看,<%= %>表达式并没有像我一直认为的那样被翻译成文字控件.但是,在呈现页面时,它会被评估并直接写入HtmlTextWriter.但显然解析器(我不确定这是将ASP.NET标记转换为.NET代码的部分的正确术语)<%= %>在将它们用作服务器控件的属性值时甚至不会尝试计算表达式.它只是将它用作字符串.我猜这就是为什么我收到错误消息:无法从'Visible'属性的字符串表示'<%= true%>'创建'System.Boolean'类型的对象.

如果我改为抛弃runat ="server"并将其<%= %>与常规的html-markup 相结合,如下所示:

<input type="button" id="Button1" visible='<%= true %>' />
Run Code Online (Sandbox Code Playgroud)

然后解析器只是在表达式之前和之后将块拆分为部分,然后将其写入render方法中的HtmlTextWriter.像这样的东西:

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

作为我注意到的最后一件事...当我尝试<%# %>+ 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;
}
Run Code Online (Sandbox Code Playgroud)

从:

<asp:Button ID="databoundButton" Visible='<%# true %>' runat="server" />
Run Code Online (Sandbox Code Playgroud)

请注意,button.Visible = true;这是<%# %>表达式的结果.

所以我的问题是..为什么第一个例子中的表达式只是被视为一个字符串,而不是被评估为"true".对于其他两个示例,表达式有些类似,它们产生了我预期的代码.

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

Jul*_*iet 94

这个:

<asp:Button runat="server" id="Button1" visible='<%= true %>' />
Run Code Online (Sandbox Code Playgroud)

不评估这个:

<asp:Button runat="server" id="Button1" visible='true' />
Run Code Online (Sandbox Code Playgroud)

<%=%>直接输出到响应流,而asp标记不是响应流的一部分.假设<%=%>运算符在asp标记上执行任何类型的预处理是错误的.


顺便说一句,考虑到<%#%>和<%=%>运算符的ASP.NET生命周期是有帮助的.

  • <%#%>在为对象赋值方面具有更多共同语义.在ASP.NET生命周期中,在页面将第一个字节写入响应缓冲区之前评估<%#%>运算符.

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

  • +1必须两次读取这个答案才能明白这一点:**直接输出到响应流,而asp标记不是响应流的一部分**又名,`<%= true%>`不会结束`<asp:Button visible`属性,但在某个地方无关! (11认同)