Example #1
0
        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));
        }
Example #2
0
        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));
        }