ASP.NET MVC之視圖引擎
內容概覽:
ActionResult做了什么?
講到視圖引擎,不得不說ActionResult,因為在Controller中,我們看不到一點視圖引擎的影子,唯一提供線索的只有ActionResult,所以我們必須先從AcionResult下手。
下面是ASP.NET MVC提供的所有的ActionResult類型的類圖:

這其中用的最多的是ViewResult,ActionResult有一個抽象方法ExecuteResult,這個方法會向用戶的請求中寫入要輸出的內容,比如Response.Write等操作。
最具代表性的ViewResult
在ASP.NET MVC中,ViewResult用的最多,Controller有一個View方法,它來實例化一個ViewResult對象,并返回。下面是View方法:
if (model != null) {
ViewData.Model = model;
}
return new ViewResult {
ViewName = viewName,
MasterName = masterName,
ViewData = ViewData,
TempData = TempData
};
}
它實例化一個ViewResult對象,并對其ViewData、TempData賦值,以完成從Controller向頁面的傳值。ViewResult繼承自ViewResultBase,ViewResult有一個IView類型的View屬性,IView接口只有一個方法:
void Render(ViewContext viewContext, TextWriter writer);
}
因此,我們推測IView用于輸出內容給用戶。ViewResult類的ExecuteResult方法證明了這一點:
if (context == null) {
throw new ArgumentNullException("context");
}
if (String.IsNullOrEmpty(ViewName)) {
ViewName = context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (View == null) {
result = FindView(context);
View = result.View;
}
ViewContext viewContext = new ViewContext(context, View, ViewData, TempData);
View.Render(viewContext, context.HttpContext.Response.Output);
if (result != null) {
result.ViewEngine.ReleaseView(context, View);
}
}
ASP.NET MVC的視圖引擎
從上一小節中,看到要想得到IView對象,必須先有ViewEngineResult對象,而ViewEngineResult對象是通過ViewResult類的FindView方法得到的:
ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);
if (result.View != null) {
return result;
}
// we need to generate an exception containing all the locations we searched
StringBuilder locationsText = new StringBuilder();
foreach (string location in result.SearchedLocations) {
locationsText.AppendLine();
locationsText.Append(location);
}
throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
MvcResources.Common_ViewNotFound, ViewName, locationsText));
}
從ViewResult類的FindView方法中,得知ViewEngineResult是通過ViewEngineCollection的FindView得到的,而ViewEngineCollection正是ViewEngines的靜態屬性Engines,Engines返回一個只有一個WebFormViewEngine類型實例的一個集合。所以,ViewEngineResult會是調用WebFormViewEngine類的FindView方法返回的結果。如果ViewEngins的靜態屬性Engines有多個ViewEngine提供,那么就依次遍歷它們直到找到第一個不為空的ViewEngineResult為止。這樣我們就可以在同一個MVC網站中使用多種視圖引擎了。
在WebFormViewEngine的FindView方法返回之前,它會為ViewEngineResult注入一個IView類型的WebFormView實例,這樣ViewEngineResult就作為一個中間人把IView類型給ViewResult了,然后ViewResult借助IView的力量,把數據輸出給用戶。
它們的關系是:
