web-dev-qa-db-fra.com

Pourquoi les expressions <% =%> en tant que valeurs de propriété sur un contrôle serveur entraînent-elles des erreurs de compilation?

Cette question est le résultat de ce que j'ai remarqué en essayant de répondre ne autre 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 cru.

D'après ce que j'ai découvert jusqu'à présent, le <%= %> 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 terme correct pour la partie qui traduit le balisage ASP.NET en code .NET) n'essaie même pas d'évaluer <%= %> expressions, lorsqu'elles sont utilisées comme valeurs de propriété pour les contrôles serveur. Il l'utilise simplement comme chaîne. Je suppose que c'est pourquoi je reçois le message d'erreur: Impossible de créer un objet de type 'System.Boolean' à partir de sa représentation sous forme de chaîne '<% = true%>' pour la propriété 'Visible' .

Si j'abandonne le runat = "server" et combine le <%= %> avec un balisage html normal, comme ceci:

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

Ensuite, l'analyseur divise simplement le morceau en parties avant et après l'expression, puis l'écrit dans HtmlTextWriter dans la méthode de rendu. Quelque chose comme ça:

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

Comme dernière chose que j'ai remarquée ... Quand j'essaie avec <%# %> + Control.DataBind (), alors j'obtiens ce que j'attendrais. Il connecte l'expression à utiliser lorsque le contrôle est lié aux données, mais contrairement à l'expression <% =%>, le code généré évalue en fait le contenu du <%# %> expression. L'analyseur finit par générer les éléments suivants:

[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" />

Remarquez le button.Visible = true; qui est le résultat du <%# %> expression.

Donc ma question est .. Pourquoi l'expression dans le premier exemple est-elle juste traitée comme une chaîne, au lieu d'être évaluée à "true". Les expressions sont quelque peu similaires pour les deux autres exemples, et elles donnent le code auquel je m'attendais.

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

50
Tom Jelen

Cette:

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

N'évalue pas cela:

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

<% =%> sort directement dans le 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 passant, cela aide à réfléchir au cycle de vie ASP.NET en ce qui concerne les opérateurs <% #%> et <% =%>.

  • <% #%> a plus de sémantique en commun avec l'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 toutes nos liaisons de données et tous les traitements de formulaires, puis exporter le code HTML vers le tampon de réponse à la toute fin du cycle de vie ASP.NET.

94
Juliet