首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 控制項轉字串工具類:RenderControl 靈活擷取 HTML 輸出

     編輯:關於ASP.NET

在 ASP.NET 開發中,常需將伺服器控制項(含整個 `.aspx` 頁面)渲染為 HTML 字串,用於:郵件內容產生、PDF 匯出、XSLT 轉換、快取片段、記錄測試輸出等。本文提供通用的 `Render` 工具類(C# / VB.NET 雙版本),封裝 `HtmlTextWriter` + `StringWriter` 模式,三種多載涵蓋所有常見場景。

核心原理

ASP.NET 控制項透過 `RenderControl(HtmlTextWriter)` 輸出 HTML。將 `HtmlTextWriter` 包裝在 `StringWriter` 上,即可捕獲輸出字串:

var sb = new StringBuilder();
var sw = new StringWriter(sb);
var hw = new HtmlTextWriter(sw);
control.RenderControl(hw);
return sb.ToString();

完整工具類實作

C# 版本

using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;

public class Render
{
    /// 渲染任意 Control 為字串
    public static string RenderControl(Control control)
    {
        var sb = new StringBuilder(1024);
        control.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
        return sb.ToString();
    }

    /// 渲染 TemplateControl (Page/UserControl) 為字串
    public static string RenderControl(TemplateControl control)
    {
        var sb = new StringBuilder(1024);
        control.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
        return sb.ToString();
    }

    /// 透過 Server.Execute 執行指定 .aspx 頁面並取得輸出
    public static string RenderPage(string pageLocation)
    {
        var context = HttpContext.Current;
        var sb = new StringBuilder(1024);
        context.Server.Execute(pageLocation, new HtmlTextWriter(new StringWriter(sb)));
        return sb.ToString();
    }
}

VB.NET 版本

Imports System
Imports System.IO
Imports System.Text
Imports System.Web
Imports System.Web.UI

Public Class Render
    Public Shared Function RenderControl(ByVal control As Control) As String
        Dim sb As New StringBuilder(1024)
        control.RenderControl(New HtmlTextWriter(New StringWriter(sb)))
        Return sb.ToString()
    End Function

    Public Shared Function RenderControl(ByVal control As TemplateControl) As String
        Dim sb As New StringBuilder(1024)
        control.RenderControl(New HtmlTextWriter(New StringWriter(sb)))
        Return sb.ToString()
    End Function

    Public Shared Function RenderPage(ByVal pageLocation As String) As String
        Dim context As HttpContext = HttpContext.Current
        Dim sb As New StringBuilder(1024)
        context.Server.Execute(pageLocation, New HtmlTextWriter(New StringWriter(sb)))
        Return sb.ToString()
    End Function
End Class

三大使用場景範例

1. 產生郵件 HTML 內容

var emailBody = Render.RenderControl(pnlEmailTemplate);
// 或指定頁面
var emailBody = Render.RenderPage("~/Templates/Email/OrderConfirm.aspx");
SendMail("user@example.com", "訂單確認", emailBody, true);

2. XSLT 轉換頁面輸出

string html = Render.RenderControl(myDataGrid);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("transform.xslt");
using (var output = new StringWriter())
{
    xslt.Transform(new XPathDocument(new StringReader(html)), null, output);
    string pdfHtml = output.ToString(); // 後續轉 PDF
}

3. 全域快取頁面片段

string cachedHtml = Cache["HeaderMenu"] as string;
if (cachedHtml == null)
{
    cachedHtml = Render.RenderControl(ucHeaderMenu);
    Cache.Insert("HeaderMenu", cachedHtml, null, DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration);
}
litHeader.Text = cachedHtml;

重要限制與注意事項

限制說明替代方案
需在 Page 生命週期中執行`RenderControl` 需控制項已建立控制項樹在 `Page_Load` 之後、`Page_Render` 之前呼叫
`Server.Execute` 會觸發完整頁面生命週期包含 `Page_Init`、`Page_Load` 等事件確保目標頁面無副作用(如重複寫入 DB)
驗證控制項需 `
`
否則 `RenderControl` 會拋出例外呼叫 `Page.VerifyRenderingInServerForm(control)`
非同步頁面/非同步控制項可能導致死鎖或輸出不完整改用 `HttpContext.Current.Response.Write` 串流輸出

現代化替代方案(ASP.NET Core / Razor)

  • `IViewRenderService` + `ViewEngine` 渲染 Razor View 為字串
  • `RazorLight`、`Scriban` 等獨立模板引擎,脫離 HTTP Context
  • Razor Class Library (RCL) 共享模板跨專案使用

此 `Render` 工具類雖屬 WebForms 時代產物,但其核心思想——**捕獲渲染管線輸出**——在現代框架中依然適用,理解其運作機制有助於跨時代技術遷移與整合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved