2008-12-16 10 views
46

To pytanie jest wynikiem tego, co zauważyłem, próbując odpowiedzieć na another question. I teraz jestem ciekawy, dlaczego <asp:TextBox runat="server" Visible="<%= true %>" /> prowadzi do błędu kompilacji, a nie do widocznego TextBox, jak bym się spodziewał.Dlaczego wyrażenia <%= %> jako wartości właściwości na serwerze prowadzą do błędów kompilacji?

Z tego, co odkryłem do tej pory, wyrażenia <%= %> nie są tłumaczone na dosłowne elementy sterujące, jak zawsze sądziłem. Zamiast tego jest on oceniany i zapisywany bezpośrednio do HtmlTextWriter podczas renderowania strony. Ale najwyraźniej analizator składni (nie jestem pewien, czy jest to poprawny termin dla części tłumaczącej znaczniki ASP.NET na kod .NET), nie próbuje nawet wyrażać wyrażeń <%= %>, gdy są one używane jako wartości właściwości dla elementów sterujących serwera. Po prostu używa go jako ciąg. Który domyślam się, dlaczego otrzymuję komunikat o błędzie: Nie można utworzyć obiektu typu "System.Boolean" z jego reprezentacji ciąg "<% = true%>" dla właściwości "Visible".

Gdybym zamiast rowu runat = „server” i łączy <%= %> regularne HTML znaczników, tak:

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

Następnie parser tylko dzieli kawałek w części przed i po wyrażeniu a następnie zapisuje go do HtmlTextWriter w metodzie renderowania. Coś takiego:

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

Jako ostatnią rzeczą, jaką zauważyłem ... Gdy próbuję z <%# %> + Control.DataBind(), a następnie pojawia się co by się spodziewać. Przywołuje wyrażenie, które ma być użyte, gdy formant kontrolny jest databound, ale w przeciwieństwie do wyrażenia <% =%>, wygenerowany kod faktycznie ocenia zawartość wyrażenia <%# %>. Parser kończy generowanie następujące:

[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; 
} 

Od:

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

obwieszczeniu button.Visible = true; który jest wynikiem ekspresji <%# %>.

Moje pytanie brzmi .. Dlaczego wyrażenie w pierwszym przykładzie jest traktowane jako ciąg, zamiast być oceniane jako "prawda". Wyrażenia są nieco podobne w przypadku dwóch innych przykładów i dają kod, jakiego oczekiwałbym.

Czy to tylko pomyłka (co wątpię, ponieważ nie jest to nowy problem z aktualną wersją ASP.NET), czy też jest jakiś dobry powód, dla którego nie wolno nam używać takiego <%= %>?

Odpowiedz

90

to:

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

nie ocenia się następująco:

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

<% =%> wyświetla się bezpośrednio do strumienia odpowiedzi i znaczniki ASP nie jest częścią strumienia reakcji. Błędem jest zakładanie, że operatorzy <% =%> wykonują jakiekolwiek wstępne przetwarzanie na znaczniku asp.


Pomaga nam myśleć o ASP.Cykl życia NET w odniesieniu do operatorów <% #%> i <% =%>.

  • <% #%> semantykę ma więcej wspólnego z przypisanie wartości do obiektu. W cyklu życia ASP.NET operatory <% #%> są obliczane zanim strona zapisze pierwszy bajt w buforze odpowiedzi.

  • <% =%> oznacza to samo co Response.Write. Najpierw musimy wykonać wszystkie nasze przetwarzanie danych i formularzy, a następnie wyprowadzić kod HTML do bufora odpowiedzi na samym końcu cyklu życia ASP.NET.

+0

Dzięki, ma to sens, pasuje do tego, co widziałem w Reflectorze. Sądzę, że miałem nadzieję, że efekt "Response.Write" był tylko konsekwencją tego, jak go użyłem, a nie sposób, w jaki został wykonany. –

+11

+1 Musiałem przeczytać tę odpowiedź dwa razy, aby uchwycić punkt: ** bezpośrednio do strumienia odpowiedzi, a znacznik asp nie jest częścią strumienia odpowiedzi ** aka, '<%=true%>' nie kończy się na ' Andomar

+0

Musisz również wywołać Button1.DataBind() w PageLoad method –

Powiązane problemy