2008-12-16 6 views
46

Cette question est le résultat de ce que j'ai remarqué en essayant de répondre another question. Et maintenant je suis curieux de savoir pourquoi <asp:TextBox runat="server" Visible="<%= true %>" /> conduit à une erreur de compilation, et non à une TextBox visible comme je l'aurais prévu. D'après ce que j'ai découvert jusqu'à présent, les expressions <%= %> ne sont pas traduites en commandes littérales comme je l'ai toujours pensé. Mais à la place, il est évalué et écrit directement dans HtmlTextWriter lorsque la page est rendue. Mais apparemment l'analyseur (je ne suis pas sûr que ce soit le bon terme pour traduire le balisage ASP.NET en code .NET) n'essaie même pas d'évaluer les expressions <%= %>, lorsqu'elles sont utilisées comme valeurs de propriété pour les contrôles serveur. Il l'utilise simplement comme une chaîne. Ce qui est pourquoi je reçois le message d'erreur: Impossible de créer un objet de type 'System.Boolean' à partir de sa représentation de chaîne '<% = true%>' pour la propriété 'Visible'.Pourquoi les expressions <%= %> en tant que valeurs de propriété sur un serveur-contrôles conduisent-elles à des erreurs de compilation?

Si je place Ditch le runat = « server » et combine les <%= %> avec HTML régulier, comme ceci:

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

Ensuite, l'analyseur divise tout le morceau dans les parties avant et après l'expression et l'écrit dans le HtmlTextWriter dans la méthode render. Quelque chose comme ceci:

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

Comme la dernière chose que j'ai remarqué ... Quand j'essaye avec <%# %> + Control.DataBind(), puis-je obtenir ce que j'attendais. Il lie l'expression à utiliser lorsque le contrôle est databound, mais contrairement à l'expression <% =%>, le code généré évalue réellement le contenu de l'expression <%# %>. L'analyseur finit par générer le texte suivant:

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

de:

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

Indication du button.Visible = true; qui est le résultat de l'expression <%# %>. Donc, ma question est .. Pourquoi est-ce que l'expression dans le premier exemple est juste traitée comme une chaîne, au lieu d'être évaluée à "vrai". Les expressions sont quelque peu similaires pour les deux autres exemples, et ils donnent le code que je m'attendais.

Est-ce juste une erreur (ce qui je doute car ce n'est pas un nouveau problème avec la version actuelle d'ASP.NET), ou y at-il une bonne raison pour laquelle nous ne sommes pas autorisés à utiliser <%= %>?

Répondre

90

Ce:

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

n'évalue pas ceci:

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

<% =%> sorties directement au flux de réponse, et le balisage asp ne fait pas partie du flux de réponse. C'est une erreur de supposer que les opérateurs <% =%> effectuent tout type de pré-traitement sur le balisage ASP.


En aparté, il est utile de penser à l'ASP.Cycle de vie NET par rapport aux opérateurs <% #%> et <% =%>.

  • <% #%> a une sémantique plus en commun avec attribution d'une valeur à un objet. Dans le cycle de vie ASP.NET, les opérateurs <% #%> sont évalués avant que la page n'écrive le premier octet dans le tampon de réponse.

  • <% =%> signifie la même chose que Response.Write. Nous devons d'abord effectuer l'ensemble de la liaison de données et du traitement des formulaires, puis afficher le code HTML dans le tampon de réponse à la toute fin du cycle de vie ASP.NET.

+0

Merci, c'est logique, ça correspond à ce que j'ai vu dans Reflector. Je suppose que j'espérais que l'effet "Response.Write" n'était qu'une conséquence de la façon dont je l'utilisais, et non pas de la façon dont il fallait travailler. –

+11

+1 A dû lire cette réponse deux fois pour attraper le point: ** sorties directement au flux de réponse, et le balisage d'asp ne fait pas partie du flux de réponse ** aka, '<%=true%>' ne finit pas dans le ' Andomar

+0

Vous devez également appeler Button1.DataBind() dans la méthode PageLoad –

Questions connexes