代碼復用方式對比
| 方式 | 特點 | 適用場景 |
| 程序集 (.dll) | 最高級,編譯後 IL,版本管理強 | 通用組件、第三方庫 |
<%@ Inherits Src %> | 繼承自定義 Page 基類 | 基類功能擴展 |
<%@ Script Src %> | 分離服務端腳本塊 | 邏輯代碼分文件 |
| 用戶控件 (.ascx) | 封裝 UI+邏輯為控件 | 可複用頁面區塊 |
| Include 指令 | 靜態文本包含,編譯前合併 | 頁面骨架拆分、靜態區塊復用 |
Response.WriteFile() | 僅輸出純客戶端代碼 | 靜態 HTML/JS/CSS 注入 |
實驗場景:「上-中-下」頁面結構
將頁頭、主體、頁腳拆為三個文件,主體作為「主文件」包含另外兩個。
head.aspx(頁頭)
<script runat="server">
void click1(object a, EventArgs b) {
label1.Text = text1.Text;
label2.Text = text2.Text;
}
</script>
<h1>The Softzz's New page</h1>
<p>2004-11-15</p>
Name: <asp:textbox id="text1" runat="server"/>
Pass: <asp:textbox id="text2" runat="server" textmode="password"/>
<asp:button id="button1" runat="server" Text="ClickMe" OnClick="click1"/>
<hr width="80%" size="1" />
end.a(頁腳,擴展名任意)
<script runat="server">
void click2(object a, EventArgs b) {
label1.Text = text3.Text;
label2.Text = text4.Text;
}
</script>
<hr width="80%" size="1" />
Name: <asp:textbox id="text3" runat="server"/>
Pass: <asp:textbox id="text4" runat="server" textmode="password"/>
<asp:button id="button2" runat="server" Text="ClickMe" OnClick="click2"/>
<h5><%= DateTime.Now.ToString() %></h5>
<b><p>CopyRight: SoftZZ</p></b>
index.aspx(主文件)
<%@ Page Language="C#" %>
<center>
<form runat="server">
<!-- #include file="head.aspx" -->
<br/>
<p>This is a new test page.Please look at the info:</p>
<br/><br/>
User's Name: <b><asp:label id=label1 runat=server/></b>
<br/><br/>
User's Pass: <b><asp:label id=label2 runat=server/></b>
<br/><br/>
<!-- #include file="end.a" -->
</form>
</center>
Include 核心機制與關鍵限制
- 編譯前文本合併:ASP.NET 編譯器先將所有 include 文件按順序拼接成單一臨時文件,再進行語法檢查/編譯。因此被包含文件只是「片段」,不需完整頁面結構。
- 標識符不能重複:多次 include 同一文件,或不同文件定義相同 ID 的
runat="server" 控件/變量/方法,會導致編譯錯誤(重複聲明)。
- 單一 <form runat="server">:整個合併後頁面只能有一個服務端表單,且必須包裹所有服務端控件。主文件放置 form 標籤最安全。
<script runat="server"> 可多處出現:它們屬於「聲明塊」,合併後順序執行,與頁面可視位置無關。
- 文件擴展名不限:.aspx、.ascx、.a、.inc 皆可,編譯器僅按文本處理。
- 路徑解析:
file="相對路徑" 相對當前文件;virtual="/虛擬路徑" 相對應用根目錄。
優缺點總結與現代替代方案
| 優點 | 缺點 | 現代替代 |
| 極簡單、無學習成本、零配置 |
無類型安全、無智能感知、難以重構 |
用戶控件、母版頁面、Razor Partial、Blazor 組件 |
| 可包含任意服務端代碼片段 |
變量/控件作用域混亂,易產生命名衝突 |
ViewComponent、TagHelper、服務端組件 |
| 舊項目維護零成本 |
不支援現代 DI、模型綁定、異步流 |
逐步遷移至模組化架構 |
最佳實踐建議
- 僅用於**純靜態/極少邏輯**的頁頭頁腳、版權聲明、通用導航欄。
- 被包含文件**不要**包含
<form>、<html>、<body> 等結構標籤。
- 控件 ID 命名加前綴(如
head_text1、foot_text3)避免衝突。
- 新項目**強烈建議**使用母版頁面或組件化方案,Include 僅作過渡或維舊。