web-dev-qa-db-ja.com

サーバーコントロールのプロパティ値として<%=%>式がコンパイルエラーにつながるのはなぜですか?

この質問は、私が 別の質問 に答えようとしたときに気付いたことの結果です。そして今、なぜ<asp:TextBox runat="server" Visible="<%= true %>" />がコンパイルエラーを引き起こし、私が期待したような目に見えるTextBoxを引き起こさないのかを知りたいと思っています。

私がこれまでに発見したことから、<%= %>式は、私がいつも考えていたとおり、リテラルコントロールに変換されません。ただし、代わりに評価され、ページのレンダリング時にHtmlTextWriterに直接書き込まれます。しかし、どうやらパーサー(ASP.NETマークアップを.NETコードに変換している部分の正しい用語かどうかはわかりません)がプロパティ値として使用される場合、<%= %>式を評価しようとさえしません。サーバーコントロール用。文字列として使用します。エラーメッセージが表示される理由は次のとおりです:「Visible」プロパティの文字列表現「<%= true%>」から「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;式の結果である<%# %>に注意してください。

だから私の質問は..最初の例の式が「true」に評価されるのではなく、文字列として扱われるのはなぜですか。式は、他の2つの例とやや似ており、予想されるコードを生成します。

それは単なる間違いですか(ASP.NETの現在のバージョンでは新しい問題ではないので疑わしい)、またはそのような<%= %>の使用が許可されない正当な理由がありますか?

50
Tom Jelen

この:

<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を応答バッファーに出力する必要があります。

94
Juliet