Почему выражения <% =%> как значения свойств серверных элементов управления приводят к ошибкам компиляции?
Этот вопрос является результатом того, что я заметил, пытаясь ответить на другой вопрос. А теперь мне интересно узнать почему <asp:TextBox runat="server" Visible="<%= true %>" />
приводит к ошибке компиляции, а не к видимому TextBox, как я бы ожидал.
Из того, что я обнаружил до сих пор, <%= %>
выражения не переводятся в буквальный контроль, как я всегда думал. Но вместо этого он оценивается и записывается непосредственно в HtmlTextWriter при визуализации страницы. Но, очевидно, синтаксический анализатор (я не уверен, что это правильный термин для части, которая переводит разметку ASP.NET в код.NET) даже не пытается оценить <%= %>
выражения, когда они используются в качестве значений свойств для серверных элементов управления. Он просто использует его как строку. Я думаю, именно поэтому я получаю сообщение об ошибке: Не удается создать объект типа "System.Boolean" из его строкового представления "<% = true%>" для свойства "Видимый".
Если я вместо того, чтобы бросить runat="сервер" и объединяет <%= %>
с обычной HTML-разметкой, вот так:
<input type="button" id="Button1" visible='<%= true %>' />
Затем синтаксический анализатор просто разделяет фрагмент на части до и после выражения, а затем записывает его в 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;
это результат <%# %>
выражение.
Так что мой вопрос... Почему выражение в первом примере просто обрабатывается как строка, а не оценивается как "истина". Выражения несколько похожи для двух других примеров, и они дают код, который я ожидал.
Это просто ошибка (в чем я сомневаюсь, поскольку это не новая проблема с текущей версией ASP.NET), или есть веская причина, по которой нам не разрешают использовать <%= %>
как это?
1 ответ
Это:
<asp:Button runat="server" id="Button1" visible='<%= true %>' />
Не оценивает это:
<asp:Button runat="server" id="Button1" visible='true' />
<% =%> выводится непосредственно в поток ответов, а разметка asp не является частью потока ответов. Ошибочно полагать, что операторы <% =%> выполняют любую предварительную обработку над разметкой asp.
Кроме того, это помогает подумать о жизненном цикле ASP.NET относительно операторов <% #%> и <% =%>.
<% #%> имеет семантику больше общего с назначением значения объекту. В жизненном цикле ASP.NET операторы <% #%> оцениваются до того, как страница записывает первый байт в буфер ответа.
<% =%> означает то же самое, что и Response.Write. Сначала нам нужно выполнить всю нашу привязку данных и обработку форм, а затем вывести HTML-код в буфер ответов в самом конце жизненного цикла ASP.NET.