接着上篇asp.net mvc源码分析-ActionResult篇 ViewResult 中有ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName)这么一句,它究竟是怎么找到View的了?首先放我们看看你ViewEngineCollection中的FindView方法吧,其实就一句
return Find(e => e.FindView(controllerContext, viewName, masterName, true),
e => e.FindView(controllerContext, viewName, masterName, false));
不过这句干的事情可不少啊,调用内部的一个Find方法,
private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> cacheLocator, Func<IViewEngine, ViewEngineResult> locator) {
// First, look up using the cacheLocator and do not track the searched paths in non-matching view engines
// Then, look up using the normal locator and track the searched paths so that an error view engine can be returned
return Find(cacheLocator, trackSearchedPaths: false)
?? Find(locator, trackSearchedPaths: true);
}
这里的cacheLocator=e.FindView(controllerContext, viewName, masterName, true),locator=e.FindView(controllerContext, viewName, masterName, false),它也是在调用一个内部的find方法,
private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> lookup, bool trackSearchedPaths) {
// Returns
// 1st result
// OR list of searched paths (if trackSearchedPaths == true)
// OR null
ViewEngineResult result;
List<string> searched = null;
if (trackSearchedPaths) {
searched = new List<string>();
}
foreach (IViewEngine engine in CombinedItems) {
if (engine != null) {
result = lookup(engine);
if (result.View != null) {
return result;
}
if (trackSearchedPaths) {
searched.AddRange(result.SearchedLocations);
}
}
}
if (trackSearchedPaths) {
// Remove duplicate search paths since multiple view engines could have potentially looked at the same path
return new ViewEngineResult(searched.Distinct().ToList());
}
else {
return null;
}
}
其中 trackSea