ViewEngine 負責「模板定位 → 編譯/解析 → 渲染輸出」全流程。本文回顧 MVC 1 時代的原始實現,對比現代 Razor 引擎的架構優勢。
早期 WebFormViewEngine 核心邏輯極其樸素:
public void RenderView(ViewContext viewContext) {
string viewLocation = ViewLocator.GetViewLocation(viewContext, viewContext.ViewName);
string viewPath = viewContext.HttpContext.Request.MapPath(viewLocation);
string viewTemplate = File.ReadAllText(viewPath); // 讀取檔案
IRenderer renderer = new PrintRenderer();
viewTemplate = renderer.Render(viewTemplate, viewContext); // 正則替換 <%= %> 標記
viewContext.HttpContext.Response.Write(viewTemplate); // 直接輸出
}

PrintRenderer 以正則匹配 <%= ... %>,效能差、功能弱(不支援邏輯控制流)。ViewDataDictionary 傳遞資料,型別不安全。BuildManager 動態編譯 .aspx/.ascx 為類別,首次請求編譯後快存,後續請求直接實例化執行。ViewPage<TModel>。<%: %>, <% %>),HTML 與代碼混雜,智能提示弱。
@model, @foreach, @if, @Html.Partial(),無需閉合標記。.Mobile.cshtml。public class ThemedRazorViewEngine : RazorViewEngine {
public ThemedRazorViewEngine(string theme) {
ViewLocationFormats = new[] {
$"~/Themes/{theme}/Views/{{1}}/{{0}}.cshtml",
$"~/Themes/{theme}/Views/Shared/{{0}}.cshtml"
};
}
}
// Global.asax 註冊
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ThemedRazorViewEngine("Default"));
| 指標 | MVC 1 (字串) | WebFormViewEngine | Razor |
|---|---|---|---|
| 首次請求延遲 | 低(無編譯) | 高(動態編譯) | 高(解析+編譯) |
| 後續請求吞吐 | 極低 | 中(快取類別) | 高(強型別、優化 IL) |
| 記憶體佔用 | 低 | 中 | 中(編譯組件) |
| 開發體驗 | 差 | 一般 | 優 |
從字串替換到動態編譯,再到 Roslyn 編譯管線,ViewEngine 演進見證了「約定優於配置」與「開發體驗至上」的工程哲學。現代專案強烈建議全面採用 Razor,舊專案可漸進式遷移(同專案共存 ASPX/Razor)。