Freigeben über


Получение 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. А вот, к примеру, для элементов упрваления, которые используют состояния серверной стороны или базы это не нужно. Видимо так.