Получение HTML разметки элемента управления
Интересный вопрос задали мне сегодня – как можно получить код разметки элемента управления в виде строки. Например, если этот фрагмент HTML как-то должен быть использован в веб-службе, либо возвращен в качестве ответа на Ajax запрос или сохранена в файл после трансформации.
Сделать это можно очень просто. Представим себе, что у нас есть следующий контрол:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DataControl.ascx.cs"
Inherits="DemoWebApp.Pages.DataControl" %>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" XPath="/feed/item" DataFile="~/App_Data/Data.xml">
</asp:XmlDataSource>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="XmlDataSource1">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# XPath("date") %>
</td>
<td>
<%# XPath("title")%><br />
<%# XPath("text")%>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Мы можем получить HTML разметку для него следующим образом:
public string GetControlHtmlMarkup()
{
Page pg = new Page();
UserControl uc = (UserControl)pg.LoadControl("~/Pages/DataControl.ascx");
pg.Controls.Add(uc);
StringWriter sw = new StringWriter();
HttpContext.Current.Server.Execute(pg, sw, false);
return sw.ToString();
}
Процесс прост – создаем объект страницы Page, добавляем на него элемент управления, выполняем страницу в текущем контексте сервера и возвращаем полученную разметку. В результате получаем что-то вроде:
<table>
<tr>
<td>01/02/2010</td>
<td> Title 1<br />This is a short text.</td>
</tr>
<tr>
<td> 11/02/2010 </td>
<td> Title 2 - Hello<br /> Lorem lorem, ipsum ipsum. </td>
</tr>
</table>
Comments
Anonymous
April 01, 2010
Гайдар, вот интересно, а будет ли, на твой взгляд, работать вариант без Page и без HttpContext.Current.Server.Execute // Тут если тип не доступен, то можно забабахать и // new Page().LoadControl("~/UserControls/SomeUserControl.ascx"); var uc = new SomeUserControl(); var sw = new StringWriter(); var wr = new HtmlTextWriter(sw); uc.RenderControl(wr); String result = sw.ToString(); Ну вроде так по памяти. Мне кажется я когда-то это делал в Remoting вообще вне HttpContext. Интересно, почему тебя потянуло на Server.Execute? Была же причина, наверное? Хотя, видимо, Server.Execute тоже не создает никакой нагрузки особой.Anonymous
April 01, 2010
Пока домой ехал - вспомнил почему. Видимо, это нужно для контролов, которые отрисовываются зависимо от состояний запроса. Т.е. они запросо-зависимые. И кастомный код таких контролов реагирует на состояния запроса. Такой контрол может часто даже порвать, т.к. редко кто ожидает, например HttpContext.Current == null. А вот, к примеру, для элементов упрваления, которые используют состояния серверной стороны или базы это не нужно. Видимо так.