private RazorPageResult LocatePageFromViewLocations( ActionContext context, string pageName, bool isPartial) { // Initialize the dictionary for the typical case of having controller and action tokens. var areaName = GetNormalizedRouteValue(context, AreaKey); // Only use the area view location formats if we have an area token. var viewLocations = !string.IsNullOrEmpty(areaName) ? AreaViewLocationFormats : ViewLocationFormats; var expanderContext = new ViewLocationExpanderContext(context, pageName, isPartial); if (_viewLocationExpanders.Count > 0) { expanderContext.Values = new Dictionary <string, string>(StringComparer.Ordinal); // 1. Populate values from viewLocationExpanders. // Perf: Avoid allocations for (var i = 0; i < _viewLocationExpanders.Count; i++) { _viewLocationExpanders[i].PopulateValues(expanderContext); } } // 2. With the values that we've accumumlated so far, check if we have a cached result. IEnumerable <string> locationsToSearch = null; var cachedResult = _viewLocationCache.Get(expanderContext); if (!cachedResult.Equals(ViewLocationCacheResult.None)) { if (cachedResult.IsFoundResult) { var page = _pageFactory.CreateInstance(cachedResult.ViewLocation); if (page != null) { // 2a We have a cache entry where a view was previously found. return(new RazorPageResult(pageName, page)); } } else { locationsToSearch = cachedResult.SearchedLocations; } } if (locationsToSearch == null) { // 2b. We did not find a cached location or did not find a IRazorPage at the cached location. // The cached value has expired and we need to look up the page. foreach (var expander in _viewLocationExpanders) { viewLocations = expander.ExpandViewLocations(expanderContext, viewLocations); } var controllerName = GetNormalizedRouteValue(context, ControllerKey); locationsToSearch = viewLocations.Select( location => string.Format( CultureInfo.InvariantCulture, location, pageName, controllerName, areaName )); } // 3. Use the expanded locations to look up a page. var searchedLocations = new List <string>(); foreach (var path in locationsToSearch) { var page = _pageFactory.CreateInstance(path); if (page != null) { // 3a. We found a page. Cache the set of values that produced it and return a found result. _viewLocationCache.Set(expanderContext, new ViewLocationCacheResult(path, searchedLocations)); return(new RazorPageResult(pageName, page)); } searchedLocations.Add(path); } // 3b. We did not find a page for any of the paths. _viewLocationCache.Set(expanderContext, new ViewLocationCacheResult(searchedLocations)); return(new RazorPageResult(pageName, searchedLocations)); }
private ViewEngineResult LocateViewFromViewLocations(ActionContext context, string viewName, bool partial) { // Initialize the dictionary for the typical case of having controller and action tokens. var routeValues = context.RouteData.Values; var areaName = routeValues.GetValueOrDefault <string>(AreaKey); // Only use the area view location formats if we have an area token. var viewLocations = !string.IsNullOrEmpty(areaName) ? AreaViewLocationFormats : ViewLocationFormats; var expanderContext = new ViewLocationExpanderContext(context, viewName); if (_viewLocationExpanders.Count > 0) { expanderContext.Values = new Dictionary <string, string>(StringComparer.Ordinal); // 1. Populate values from viewLocationExpanders. foreach (var expander in _viewLocationExpanders) { expander.PopulateValues(expanderContext); } } // 2. With the values that we've accumumlated so far, check if we have a cached result. var viewLocation = _viewLocationCache.Get(expanderContext); if (!string.IsNullOrEmpty(viewLocation)) { var page = _pageFactory.CreateInstance(viewLocation); if (page != null) { // 2a. We found a IRazorPage at the cached location. return(CreateFoundResult(context, page, viewName, partial)); } } // 2b. We did not find a cached location or did not find a IRazorPage at the cached location. // The cached value has expired and we need to look up the page. foreach (var expander in _viewLocationExpanders) { viewLocations = expander.ExpandViewLocations(expanderContext, viewLocations); } // 3. Use the expanded locations to look up a page. var controllerName = routeValues.GetValueOrDefault <string>(ControllerKey); var searchedLocations = new List <string>(); foreach (var path in viewLocations) { var transformedPath = string.Format(CultureInfo.InvariantCulture, path, viewName, controllerName, areaName); var page = _pageFactory.CreateInstance(transformedPath); if (page != null) { // 3a. We found a page. Cache the set of values that produced it and return a found result. _viewLocationCache.Set(expanderContext, transformedPath); return(CreateFoundResult(context, page, transformedPath, partial)); } searchedLocations.Add(transformedPath); } // 3b. We did not find a page for any of the paths. return(ViewEngineResult.NotFound(viewName, searchedLocations)); }