Как изменить содержимое всей страницы ASP.NET прямо перед ее выходом?

У меня есть страница, на которой есть куча пользовательских элементов управления. Я хочу иметь "макросы" или "заполнители" непосредственно в содержимом, которое будет заменено в моем коде. Это не имеет никакого значения, но я использую Ektron как свою CMS.

Есть ли какие-либо события на странице, которые я могу подключить, чтобы выполнить замену строки во всем содержимом отображаемой страницы прямо перед отправкой клиенту?

UPDATE

Вот код, который я использую для этого:

protected override void Render(HtmlTextWriter writer)
{
    string content = string.Empty;

    using (var stringWriter = new StringWriter())
    using (var htmlWriter = new HtmlTextWriter(stringWriter))
    {
        // render the current page content to our temp writer
        base.Render(htmlWriter);
        htmlWriter.Close();

        // get the content
        content = stringWriter.ToString();
    }

    // replace our placeholders
    string newContent = content.Replace("$placeholder1$", "placeholder1 data").Replace("$placeholder2$", "placeholder2 data");

    // write the new html to the page
    writer.Write(newContent);
}

Ответ 1

Вы пытались переопределить метод рендеринга?

protected override void Render(HtmlTextWriter writer)
{
   StringBuilder htmlString = new StringBuilder(); // this will hold the string
   StringWriter stringWriter = new StringWriter(htmlString);
   HtmlTextWriter tmpWriter = new HtmlTextWriter(stringWriter);
   Page.Render(tmpWriter);
   writer.Flush();

   writer.Write(DoReplaceLogic(htmlString.ToString()););
}

Ответ 2

Я знаю, что этот ответ не поможет, так как вы уже решили эту проблему и двинулись дальше. Это просто для людей, которые столкнутся с подобной проблемой в будущем;)

Есть два подхода, которые вы могли бы использовать.

  • Это похоже на принятый ответ. Но я бы порекомендовал переопределение метода рендеринга в BasePage и выводит все ваши шаблоны из этого.

  • Используйте HttpModule или Global.asax и прикрепите Filter к ответу объект. Для меня это делает больше эстетический смысл, потому что "Фильтр" собственность должна помочь вам фильтровать вывод, который точно что вам нужно!

Кстати, как это происходит с Ektron? Они заставляют меня сходить с ума!

Ответ 3

Вы посмотрели событие PreRender в жизненном цикле?

До этого события:

• Объект страницы вызывает EnsureChildControls для каждый элемент управления и для страницы.

• Каждый управление данными, чей DataSourceID свойство задано, вызывает его DataBind метод.

• Происходит событие PreRender для каждого элемента управления на странице. Используйте для внесения окончательных изменений в содержимого страницы или ее элементов управления.

Я считаю, что это последнее место, где вы могли бы сделать что-то подобное. Следующее событие SaveStateComplete, которое, согласно документации, имеет такое поведение:

Прежде чем это событие произойдет, ViewState был сохранен для страницы и для всех элементов управления. Любые изменения в страница или элементы управления на этом этапе будут проигнорированы. Использовать это событие выполнять задачи, требующие состояния просмотра для сохранения, но это не делает изменения в элементах управления.

Ответ 4

Упрощенный ответ, который приходит на ум, - использовать asp: Literal control для ваших "заполнителей". Вы можете установить их содержимое во время загрузки страницы, или вы можете подключиться к событию PreRender и затем установить их.

Ответ 5

Похоже, вы могли бы иметь HTML-литералы на своей странице, а затем вы можете просто заменить их соответствующим контентом в событии Page_Load.

Это потребует, чтобы вы выписывали HTML-код, а не какой-то простой текст, но похоже, что вы можете вводить свой собственный код JavaScript или тому подобное, что будет отлично работать.