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

ASP.NET 換膚技術:重寫 Render 攔截 HTML 注入 CSS、HttpModule 全站套用與基類頁面兩種實作比較

     編輯:關於ASP.NET

最簡單換膚 = 切換 CSS 檔案。本文介紹兩種無需修改每個頁面的全站換膚實作:Page.Base 重寫 Render 與 HttpModule 攔截回應。

方案一:基類頁面重寫 Render (侵入式)

public class PageBase : System.Web.UI.Page
{
    protected override void Render(HtmlTextWriter writer)
    {
        using (StringWriter sw = new StringWriter())
        using (HtmlTextWriter hw = new HtmlTextWriter(sw))
        {
            base.Render(hw);
            hw.Flush();
            string html = sw.ToString();

            // 取得當前使用者選擇的 CSS URL (Session/Profile/Cookie/DB)
            string cssUrl = GetCurrentThemeCssUrl(); // 如 "/Styles/Blue.css"

            string linkTag = $"";

            // 插入到  之前
            int pos = html.IndexOf("", StringComparison.OrdinalIgnoreCase);
            if (pos > 0)
                html = html.Insert(pos, linkTag);

            writer.Write(html);
        }
    }
    private string GetCurrentThemeCssUrl() { /* 實作略 */ return "/Styles/Default.css"; }
}

所有頁面繼承 PageBase 即可自動套用。

方案二:HttpModule 非侵入式 (推薦)

public class ThemeInjectionModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostRequestHandlerExecute += OnPostRequestHandlerExecute;
    }

    private void OnPostRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
        HttpResponse response = app.Context.Response;

        // 僅處理 HTML 回應
        if (response.ContentType != "text/html") return;

        // 安裝 Response Filter
        response.Filter = new ThemeInjectionFilter(response.Filter, GetCurrentThemeCssUrl());
    }

    private string GetCurrentThemeCssUrl() { /* 實作略 */ return "/Styles/Default.css"; }
}

public class ThemeInjectionFilter : Stream
{
    private readonly Stream _baseStream;
    private readonly string _linkTag;
    private readonly MemoryStream _buffer = new MemoryStream();
    private bool _injected = false;

    public ThemeInjectionFilter(Stream baseStream, string cssUrl)
    {
        _baseStream = baseStream;
        _linkTag = $"";
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        if (!_injected)
        {
            _buffer.Write(buffer, offset, count);
            string html = Encoding.UTF8.GetString(_buffer.ToArray());
            int pos = html.IndexOf("", StringComparison.OrdinalIgnoreCase);
            if (pos >= 0)
            {
                html = html.Insert(pos, _linkTag);
                byte[] newBytes = Encoding.UTF8.GetBytes(html);
                _baseStream.Write(newBytes, 0, newBytes.Length);
                _injected = true;
                _buffer.SetLength(0); // 釋放緩衝
            }
        }
        else
        {
            _baseStream.Write(buffer, offset, count);
        }
    }
    // 其他 Stream 抽象成員轉發給 _baseStream...
}

web.config 註冊:

<system.webServer>
  <modules>
    <add name="ThemeInjection" type="MyApp.ThemeInjectionModule" />
  </modules>
</system.webServer>

兩方案比較

維度PageBase RenderHttpModule + Filter
侵入性需所有頁面繼承基類零修改,配置即生效
效能完整 HTML 進記憶體字串串流處理,記憶體友善
靈活性易於在頁面層級覆寫/排除需在 Filter 邏輯判斷排除路徑
適用範圍WebForms 傳統專案WebForms / MVC / Core 通用

進階:主題系統整合

  • web.config <pages theme="Blue" /> 或 Page.Theme = "Blue":ASP.NET 內建主題機制 (App_Themes 資料夾),自動套用 .skin/ .css。
  • 結合 Profile 儲存使用者偏好:Profile.Theme。
  • 支援巢狀 Master Page 時,CSS 注入邏輯需確保不重複插入。

HttpModule + Response Filter 是企業級全站換膚/注入 SEO/安全標頭/AMP 轉換的標準架構模式。

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