服務熱線
153 8323 9821
本文講解ViewEngine的作用, 并且深入解析了實現ViewEngine相關的所有接口和類, 最后演示了如何開發一個自定義的ViewEngine. 本系列文章已經全部更新為ASP.NET MVC 1.0版本.希望大家多多支持!
首先注意: 我會將大家在MVC之前一直使用的ASP.NET頁面編程模型稱作ASP.NET WebForm編程模型.
上一講中我們已經學習了如何向View傳遞Model, 以及如何在View中使用Model對象. 目前為止我們使用的都還是ASP.NET WebForm的頁面模型,比如aspx頁面,用戶控件,母版頁等. 最后這些頁面中都要轉換為HTML代碼. 比如頁面中的內嵌代碼:
<% = ViewData["model"] %>
你是否思考過, 為何頁面會支持<% %>這種語法? 為何最后一個aspx頁面會在瀏覽器中以HTML代碼的形式展現?
有人會回答這是ASP.NET自帶的語法和功能. 沒有錯, ASP.NET幫我們做了編譯頁面, 輸出HTML, 返回HTML給客戶端瀏覽器等一系列工作.但是這些工作在MVC框架中有很多是屬于View角色的職責. 為了繼續使用原有的ASP.NET WebForm頁面引擎, ASP.NET MVC抽象出來了ViewEngine這個角色. 顧名思義ViewEngine即視圖引擎, 其主要作用就是找到View對象, 編譯View對象中的語言代碼(執行語言邏輯), 并且輸出HTML. 下面講解的WebFormViewEngine就是使用ASP.NET WebForm的頁面編譯/呈現功能實現的.
下面將講解和ViewEngine有關的各個接口和類.
IView接口是對MVC結構中View對象的抽象, 此接口只有一個方法:
void Render(ViewContext viewContext, TextWriter writer);
Render方法的作用就是展示View對象, 通常是將頁面HTML寫入到Writer中供瀏覽器展示.
在本系列第三篇文章中我曾經分析過, 雖然IView對象是MVC中View角色的抽象, 并且提供了Render方法, 但是實際上真正的View角色的顯示邏輯在ViewPage/ViewUserControl類中. 這是由于ASP.NET MVC提供的WebFormViewEngine視圖引擎是使用原有的ASP.NET Web From的頁面顯示機制, 我們無法直接將WebForm模型中的頁面轉化為IView對象.
于是最后使用了一個折中的辦法:
在IView對象的Render方法中調用WebForm頁面的Render方法. WebFormView是目前ASP.NET MVC中唯一實現了IView接口的類
所以如果我們使用自定義的ViewEngine引擎, 就可以直接創建一個實現了IView接口的類實現Render方法.
ViewEngine即視圖引擎, 在ASP.NET MVC中將ViewEngine的作用抽象成了 IViewEngine 接口.
雖然IViewEngine的職責是尋找View對象, 但是其定義的兩個方法:
返回的結果是ViewEngineResult對象, 并不是View對象. 我們可以將ViewEngineResult理解為一次查詢的結果, 在ViewEngineResult對象中包含有本次找到的IView對象.
ASP.NET MVC 提供了下面兩個實現了IViewEngine接口的類:
WebFormViewEngine是VirtualPathProviderViewEngine的派生類.
VirtualPathProviderViewEngine類實現了FindPartialView/FindView方法, 更夠根據指定的路徑格式搜索頁面文件, 并且使用了提供了Cache機制緩存數據. 注意因為使用的是ASP.NET Cache,依賴HttpContext對象, 這就導致Cache無法在WebService或者WCf等項目中使用. VirtualPathProviderViewEngine尋找頁面的方法依賴下面三個屬性:
在VirtualPathProviderViewEngine中只定義了這三個屬性, 具體的值在派生類WebFormViewEngine中指定:
public WebFormViewEngine() {
MasterLocationFormats = new[] {
"~/Views/{1}/{0}.master",
"~/Views/Shared/{0}.master"
};
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};
PartialViewLocationFormats = ViewLocationFormats;
}
上面的代碼中我們可以一步了然ViewEngine都搜索哪些路徑.甚至還可以添加我們自己的路徑和文件類型.
因為有了VirtualPathProviderViewEngine類, 在開發自定義的ViewEngine時不需要再編寫搜索View文件的邏輯了.只需要定義搜索路徑即可. 如果不使用ASP.NET WebForm的頁面顯示方式, 就需要自己定義的View對象如何顯最后轉化為HTML代碼.
在后面的實例中會演示創建一個我們自定義的ViewEngine.
ViewEngineResult是ViewEngine尋找View的查詢結果.ViewEngineResult類沒有派生類, 也就是說不同的ViewEngine返回的結果都是ViewEngineResult對象.
ViewEngineResult類有一個很重要的構造函數:
public ViewEngineResult(IView view, IViewEngine viewEngine)
以WebFormViewEngine為例, 在WebFormViewEngine類中定義了 MasterLocationFormats/ViewLocationFormats /PartialViewLocationFormats , 在調用FindPartialView/FindView方法時, 首先找到View對象的磁盤路徑, 然后使用CreatePartialView/CreateView方法將磁盤路徑轉化實現了IView接口的WebFormView對象.
WebFormView中依然保存這頁面對象的磁盤路徑, 在調用Render時會根據磁盤路徑創建ViewPage對象, 調用頁面的Render方法.ASP.NET MVC編譯頁面時, 使用了.NET Framework 2.0以上的版本中提供的根據虛擬路徑編譯頁面的函數:
BuildManager.CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType)
命名空間為System.Web.Compilation.
ViewEngineCollection是IViewEngine對象的集合類. 在我們的系統中可以使用多個ViewEngine, 在尋找時會返回第一個匹配的ViewEngineResult, 下面是ViewEngineCollection類的Find
上一篇:怎么看百度蜘蛛什么時候來