傳統 ASP.NET 應用強依賴 IIS。但在單元測試、桌面應用內嵌報表、離線文件生成、輕量級微服務等場景,若能**直接在進程中託管 ASP.NET 執行環境**,無需安裝/配置 IIS,將極大簡化部署與測試流程。System.Web.Hosting.ApplicationHost.CreateApplicationHost 提供了這條路徑。
ApplicationHost.CreateApplicationHost 在指定物理目錄建立一個**獨立應用程式域**,載入 ASP.NET 執行階段MarshalByRefObject 代理物件,跨 AppDomain 呼叫HttpRuntime.ProcessRequest + SimpleWorkerRequest 模擬 HTTP 請求處理管線Console.Out、StringWriter 或自訂 TextWriter// MyHost.cs
// 編譯:csc MyHost.cs /r:System.Web.dll /r:System.dll
using System;
using System.IO;
using System.Web;
using System.Web.Hosting;
public class MyExeHost : MarshalByRefObject
{
public void ProcessRequest(string page)
{
// SimpleWorkerRequest(虛擬路徑, 物理路徑, 輸出流)
HttpRuntime.ProcessRequest(new SimpleWorkerRequest(page, null, Console.Out));
}
public static void Main(string[] args)
{
// 建立應用程式域:型別、虛擬路徑、物理路徑
MyExeHost host = (MyExeHost)ApplicationHost.CreateApplicationHost(
typeof(MyExeHost), "/foo", Environment.CurrentDirectory);
foreach (string page in args)
{
host.ProcessRequest(page);
}
}
}
<!-- Test.aspx 放在同目錄 --%>
<%@ Page Language="C#" %>
<html><body>
Time is now: <%= DateTime.Now %>
</body></html>
> MyHost.exe Test.aspx > Test.html
> type Test.html
Time is now: 2024-01-15 14:30:45
public string RenderPage(string pagePath)
{
using (var sw = new StringWriter())
{
HttpRuntime.ProcessRequest(new SimpleWorkerRequest(pagePath, null, sw));
return sw.ToString();
}
}
// 或導向檔案
using (var fs = new StreamWriter("output.html"))
HttpRuntime.ProcessRequest(new SimpleWorkerRequest(pagePath, null, fs));
SimpleWorkerRequest 建構函數支援:
// 完整簽名
public SimpleWorkerRequest(
string page, // 虛擬路徑 /foo/Test.aspx
string query, // 查詢字串 "id=1&name=test"
TextWriter output, // 輸出
string path, // 物理路徑(可為 null)
string filePath, // 對應實體檔案路徑
string pathInfo, // 路徑資訊
NameValueCollection headers, // 模擬 HTTP 標頭
byte[] body, // POST 資料
NameValueCollection form, // 表單集合
NameValueCollection queryString, // 查詢字串集合
NameValueCollection cookies, // Cookie
NameValueCollection serverVariables // 伺服器變數
)
可構建完整模擬請求環境,支援 Request.QueryString、Request.Form、Request.Cookies、Session(需在 web.config 啟用 SessionState)。
| 限制 | 說明 |
|---|---|
| 僅支援 .NET Framework | .NET Core / 5+ 無 System.Web.Hosting,需用 ASP.NET Core TestHost 或 Kestrel 自託管 |
| 無完整 IIS 模組管線 | URL Rewrite、輸出快取、整合式驗證等模組不生效 |
| 靜態檔案處理 | 需自行對應 .css/.js/.png 等副檔名至靜態檔案處理器 |
| 效能 | 每次請求建立 AppDomain 開銷大,適合低頻場景 |
| 信任等級 | 預設 Full Trust,部分信任環境需配置 trustLevel |
// .NET Core / 5+ 單元測試標準做法
var builder = new WebHostBuilder().UseStartup();
var server = new TestServer(builder);
var client = server.CreateClient();
var response = await client.GetAsync("/api/values");
var content = await response.Content.ReadAsStringAsync();
ApplicationHost.CreateApplicationHost 是 .NET Framework 時代「無 IIS 執行 ASPX」的經典黑科技。雖然已非主流,但在維護舊系統、生成靜態報表、整合桌面應用時仍具獨特價值。理解其原理——**跨 AppDomain 代理 + HttpRuntime 管線模擬**——有助於掌握 ASP.NET 請求處理核心架構。