Иногда в веб-приложении бывает необходимо отослать код, сгенерированный веб-контролом на email пользователю. Чаще всего это встречается в системах со всяческими отчетами. Рассмотрим как это можно реализовать.
Каждый веб-контрол имеет в себе метод , RenderControl(HtmlTextWriter) который при вызове рендерит контрол и возвращает, как результат HtmlTextWriter. Программно это выглядит так:
StringBuilder SB = new StringBuilder(); StringWriter SW = new StringWriter(SB); HtmlTextWriter htmlTW = new HtmlTextWriter(SW); WebControlToRenderID.RenderControl(htmlTW);
Однако данный подход прекрасно работающий в ASP.NET 1.1 не подходит для ASP.NET 2.0, так как при выполнении вы получите исключение: RegisterForEventValidation can only be called during Render();
Это происходит потому, что в ASP.NET 2.0 появилась новая возможность - Event Validation. Сделана она для того, чтобы помочь избежать так называемых Injection атак.
К примеру у вас на веб-форме имеется DropDownList контрол:
<asp:DropDownList runat="server" id="MyDropDownList"> <asp:ListItem Value="1">Item 1</asp:ListItem> <asp:ListItem Value="2">Item 2</asp:ListItem> <asp:ListItem Value="3">Item 3</asp:ListItem> </asp:DropDownList>
В цикле жизни страницы контрол регистрирует себя на подобную проверку через класс ClientScriptManager методом RegisterForEventValidation. Этот метод может быть вызван только на этапе Render, иначе он генерирует исключение. А так как скорее код для програмной генерации контрола вызывается до этого этапа, к примеру, в событии Button1_Click, то вы гарантировано получаете исключение.
Естественно, сказанное выше применимо только к контролам требующим Event Validation. Вот их список:
- HtmlAnchor
- HtmlButton
- HtmlInputButton
- HtmlInputCheckBox
- HtmlInputHidden
- HtmlInputImage
- HtmlInputText
- HtmlInputPassword
- HtmlInputRadioButton
- HtmlInputReset
- HtmlInputSubmit
- HtmlSelect
- HtmlTextArea
- BulletedList
- Button
- Calendar
- CheckBox
- Table
- ChildTable
- WizardChildTable
- DataControlButton
- ImageButton
- DataControlImageButton
- LinkButton
- DataControlLinkButton
- DataControlPagerLinkButton
- DataGridLinkButton
- DetailsView
- DropDownList
- FormView
- GridView
- HiddenField
- ImageMap
- LayoutTable
- ListBox
- Menu
- PagerTable
- RadioButton
- RadioButtonList
- TextBox
- TreeView
- WizardDefaultInnerTable
- CatalogZone
- ConnectionsZone
- EditorZone
- WebPartZone
- ZoneButton
- ZoneLinkButton
Или же вы можете начинать рендеринг контрола(ов) в событии Page_Render. Перевод статьи Emailing the Rendered Output of an ASP.NET Web Control in ASP.NET 2.0<% @Page EnableEventValidation="False" ... %>