RazorViewEngine → BuildManagerViewEngine → VirtualPathProviderViewEngine → IViewEngine。
~/Views/{ControllerName}/{ViewName}.cshtml~/Views/{ControllerName}/{ViewName}.vbhtml~/Views/Shared/{ViewName}.cshtml~/Views/Shared/{ViewName}.vbhtml~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.cshtml~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.vbhtml~/Areas/{AreaName}/Views/Shared/{ViewName}.cshtml~/Areas/{AreaName}/Views/Shared/{ViewName}.vbhtmlPartial View、Layout 檔案同樣套用此搜尋邏輯。
controllerName、areaName (可選)。Request.MapPath 檢查實體檔案是否存在。RazorView(virtualPath) 封裝為 ViewEngineResult 回傳。ViewEngineResult (供錯誤頁面顯示)。public void ReleaseView(ControllerContext controllerContext, IView view)
{
var disposable = view as IDisposable;
if (disposable != null) disposable.Dispose();
}

public class SimpleRazorViewEngine : IViewEngine
{
private string[] viewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" };
private string[] areaViewLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml" };
public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
=> FindView(controllerContext, partialViewName, null, useCache);
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
string controllerName = controllerContext.RouteData.GetRequiredString("controller");
object areaName;
var viewLocations = new List<string>();
Array.ForEach(viewLocationFormats, f => viewLocations.Add(string.Format(f, viewName, controllerName)));
if (controllerContext.RouteData.Values.TryGetValue("area", out areaName))
Array.ForEach(areaViewLocationFormats, f => viewLocations.Add(string.Format(f, viewName, controllerName, areaName)));
foreach (var loc in viewLocations)
{
string filePath = controllerContext.HttpContext.Request.MapPath(loc);
if (File.Exists(filePath))
return new ViewEngineResult(new SimpleRazorView(loc), this);
}
return new ViewEngineResult(viewLocations);
}
public void ReleaseView(ControllerContext controllerContext, IView view)
{
var disposable = view as IDisposable;
if (disposable != null) disposable.Dispose();
}
}
BuildManagerViewEngine 內建快取:useCache=true 時,檔案存在性檢查結果與編譯型別快取於 BuildManager。生產環境預設開啟,開發環境可關閉 (compilation debug="true")。
RazorViewEngine 以慣例優於配置定義視圖搜尋路徑,支援 Area 階層與回退機制。FindView 核心為虛擬路徑對應實體檔案檢查,找到則建立 RazorView。理解搜尋順序可正確組織專案結構,避免視圖衝突。