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

ASP.NET MVC 學習筆記 (五) ViewEngine 深度解析與自訂視圖引擎實戰

     編輯:關於ASP.NET

ViewEngine 是 MVC 中「尋找、編譯、渲染視圖」的核心抽象。本文解析 IView、IViewEngine、VirtualPathProviderViewEngine、WebFormViewEngine、RazorViewEngine 關係,並完整示範如何開發**自訂 ViewEngine** (支援自訂副檔名、非標準視圖位置、編譯緩存),附原始碼級剖析。

核心介面與類別關係圖

IView
  └─ Render(ViewContext, TextWriter)  // 唯一職責:輸出 HTML

IViewEngine
  ├─ FindView(ControllerContext, viewName, masterName, useCache) → ViewEngineResult
  └─ FindPartialView(ControllerContext, partialViewName, useCache) → ViewEngineResult

ViewEngineResult
  ├─ View (IView)           // 找到的視圖
  ├─ ViewEngine (IViewEngine) // 來源引擎
  └─ SearchedLocations (string[]) // 搜尋過的路徑 (供除錯)

VirtualPathProviderViewEngine (抽象基類)
  ├─ ViewLocationFormats / MasterLocationFormats / PartialViewLocationFormats (搜尋路徑模式)
  ├─ FileExtensions (副檔名)
  └─ CreateView / CreatePartialView (工廠方法)

WebFormViewEngine : VirtualPathProviderViewEngine  // .aspx/.ascx/.master
RazorViewEngine : VirtualPathProviderViewEngine    // .cshtml/.vbhtml

WebFormViewEngine 運作細節

  1. FindView 依 ViewLocationFormats (預設 ~/Views/{1}/{0}.aspx, ~/Views/Shared/{0}.aspx...) 尋找檔案。
  2. 找到後呼叫 CreateView → 建立 WebFormView (實作 IView)。
  3. WebFormView.Render 內部委託 BuildManager.CreateInstanceFromVirtualPath 編譯/載入頁面類別,呼叫其 Render。
  4. 支援母版頁 (masterName)、部分視圖 (FindPartialView)。

自訂 ViewEngine 實戰:支援 .html 靜態模板 + 標記語法

public class HtmlTemplateViewEngine : VirtualPathProviderViewEngine
{
    public HtmlTemplateViewEngine()
    {
        // 定義搜尋路徑與副檔名
        ViewLocationFormats = new[] { "~/Views/{1}/{0}.html", "~/Views/Shared/{0}.html" };
        PartialViewLocationFormats = new[] { "~/Views/Shared/Partials/{0}.html" };
        FileExtensions = new[] { "html" };
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        return new HtmlTemplateView(viewPath);
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new HtmlTemplateView(partialPath);
    }
}

// 簡易 IView 實作:讀取 .html 檔案,做標記替換 (如 {{Model.Title}})
public class HtmlTemplateView : IView
{
    private readonly string _viewPath;

    public HtmlTemplateView(string viewPath) => _viewPath = viewPath;

    public void Render(ViewContext viewContext, TextWriter writer)
    {
        string template = File.ReadAllText(viewContext.HttpContext.Server.MapPath(_viewPath));
        // 簡易模型綁定:替換 {{PropertyName}}
        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(viewContext.ViewData.Model))
        {
            object val = prop.GetValue(viewContext.ViewData.Model);
            template = template.Replace($"{{{{{prop.Name}}}}}", val?.ToString() ?? "");
        }
        writer.Write(template);
    }
}

註冊自訂 ViewEngine

protected void Application_Start()
{
    ViewEngines.Engines.Clear(); // 可選:移除預設引擎
    ViewEngines.Engines.Add(new HtmlTemplateViewEngine());
    // 或保留預設,僅添加:ViewEngines.Engines.Insert(0, new HtmlTemplateViewEngine());
}

進階議題

主題關鍵點
編譯快取繼承 BuildManagerCompiledView 或實作 IView 內部快取編譯結果 (如 Razor 預編譯)。
依賴注入整合ViewEngine 建構函式注入 IServiceProvider,視圖渲染時解析服務。
主題/裝置切換覆寫 FindView,依 ControllerContext.HttpContext.Request (User-Agent, Cookie) 動態調整搜尋路徑。
除錯支援ViewEngineResult.SearchedLocations 回傳嘗試路徑,ViewNotFoundException 會顯示完整列表。

結語

ViewEngine 將「視圖尋找與渲染」標準化、可替換。理解 IView/IViewEngine/VirtualPathProviderViewEngine 分層,即可開發支援**任意模板語法、儲存介質、主題切換**的自訂引擎。Razor 的成功證明:好的 ViewEngine = **語法簡潔 + 編譯快取 + 工具支援 (IntelliSense)**。自訂引擎除非有特殊需求 (舊系統遷移、非標準模板),否則優先使用內建 Razor。

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