private void EnsureCache()
        {
            lock (_cacheLock)
            {
                if (_cachedModels != null)
                {
                    return;
                }

                var rootDirectory = _pagesOptions.RootDirectory;
                if (!rootDirectory.EndsWith("/", StringComparison.Ordinal))
                {
                    rootDirectory = rootDirectory + "/";
                }

                var cachedApplicationModels = new List <PageRouteModel>();
                foreach (var viewDescriptor in GetViewDescriptors(_applicationManager))
                {
                    if (!viewDescriptor.RelativePath.StartsWith(rootDirectory, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    var viewEnginePath = GetViewEnginePath(rootDirectory, viewDescriptor.RelativePath);
                    var model          = new PageRouteModel(viewDescriptor.RelativePath, viewEnginePath);
                    var pageAttribute  = (RazorPageAttribute)viewDescriptor.ViewAttribute;
                    PageSelectorModel.PopulateDefaults(model, pageAttribute.RouteTemplate);

                    cachedApplicationModels.Add(model);
                }

                _cachedModels = cachedApplicationModels;
            }
        }
        private void AddPageModels(PageRouteModelProviderContext context)
        {
            foreach (var item in _project.EnumerateItems(_pagesOptions.RootDirectory))
            {
                if (!IsRouteable(item))
                {
                    continue;
                }

                if (!PageDirectiveFeature.TryGetPageDirective(_logger, item, out var routeTemplate))
                {
                    // .cshtml pages without @page are not RazorPages.
                    continue;
                }

                var routeModel = new PageRouteModel(
                    relativePath: item.CombinedPath,
                    viewEnginePath: item.FilePathWithoutExtension);

                if (IsAlreadyRegistered(context, routeModel))
                {
                    // The CompiledPageRouteModelProvider (or another provider) already registered a PageRoute for this path.
                    // Don't register a duplicate entry for this route.
                    continue;
                }

                PageSelectorModel.PopulateDefaults(routeModel, routeModel.ViewEnginePath, routeTemplate);
                context.RouteModels.Add(routeModel);
            }
        }
        public void OnProvidersExecuting(PageRouteModelProviderContext context)
        {
            foreach (var item in _project.EnumerateItems(_pagesOptions.RootDirectory))
            {
                if (item.FileName.StartsWith("_"))
                {
                    // Pages like _ViewImports should not be routable.
                    continue;
                }

                if (!PageDirectiveFeature.TryGetPageDirective(_logger, item, out var routeTemplate))
                {
                    // .cshtml pages without @page are not RazorPages.
                    continue;
                }

                if (IsAlreadyRegistered(context, item))
                {
                    // The CompiledPageRouteModelProvider (or another provider) already registered a PageRoute for this path.
                    // Don't register a duplicate entry for this route.
                    continue;
                }

                var routeModel = new PageRouteModel(
                    relativePath: item.CombinedPath,
                    viewEnginePath: item.FilePathWithoutExtension);
                PageSelectorModel.PopulateDefaults(routeModel, routeTemplate);

                context.RouteModels.Add(routeModel);
            }
        }
Example #4
0
        public void TryParseAreaPath_ReturnsFalse_IfPathDoesNotBelongToRootDirectory(string path)
        {
            // Arrange
            var options = new RazorPagesOptions();

            // Act
            var success = PageSelectorModel.TryParseAreaPath(options, path, NullLogger.Instance, out _);

            // Assert
            Assert.False(success);
        }
        private PageRouteModel GetPageRouteModel(string rootDirectory, CompiledViewDescriptor viewDescriptor)
        {
            var viewEnginePath = GetRootTrimmedPath(rootDirectory, viewDescriptor.RelativePath);

            if (viewEnginePath.EndsWith(RazorViewEngine.ViewExtension, StringComparison.OrdinalIgnoreCase))
            {
                viewEnginePath = viewEnginePath.Substring(0, viewEnginePath.Length - RazorViewEngine.ViewExtension.Length);
            }

            var model         = new PageRouteModel(viewDescriptor.RelativePath, viewEnginePath);
            var pageAttribute = (RazorPageAttribute)viewDescriptor.ViewAttribute;

            PageSelectorModel.PopulateDefaults(model, viewEnginePath, pageAttribute.RouteTemplate);
            return(model);
        }
Example #6
0
        public void TryParseAreaPath_ParsesAreaPath(
            string path,
            string expectedArea,
            string expectedViewEnginePath,
            string expectedRoute)
        {
            // Arrange
            var options = new RazorPagesOptions();

            // Act
            var success = PageSelectorModel.TryParseAreaPath(options, path, NullLogger.Instance, out var result);

            // Assert
            Assert.True(success);
            Assert.Equal(expectedArea, result.areaName);
            Assert.Equal(expectedViewEnginePath, result.viewEnginePath);
            Assert.Equal(expectedRoute, result.pageRoute);
        }
        private PageRouteModel GetAreaPageRouteModel(string areaRootDirectory, CompiledViewDescriptor viewDescriptor)
        {
            var rootTrimmedPath = GetRootTrimmedPath(areaRootDirectory, viewDescriptor.RelativePath);

            if (PageSelectorModel.TryParseAreaPath(_pagesOptions, rootTrimmedPath, _logger, out var result))
            {
                var model = new PageRouteModel(viewDescriptor.RelativePath, result.viewEnginePath)
                {
                    RouteValues = { ["area"] = result.areaName },
                };
                var pageAttribute = (RazorPageAttribute)viewDescriptor.ViewAttribute;
                PageSelectorModel.PopulateDefaults(model, result.pageRoute, pageAttribute.RouteTemplate);

                return(model);
            }

            // We were unable to parse the path to match the format we expect /Areas/AreaName/Pages/PagePath.cshtml
            return(null);
        }
        private void AddPageModels(PageRouteModelProviderContext context)
        {
            var normalizedAreaRootDirectory = _pagesOptions.AreaRootDirectory;

            if (!normalizedAreaRootDirectory.EndsWith("/", StringComparison.Ordinal))
            {
                normalizedAreaRootDirectory += "/";
            }

            foreach (var item in _project.EnumerateItems(_pagesOptions.RootDirectory))
            {
                if (!IsRouteable(item))
                {
                    continue;
                }

                var relativePath = item.CombinedPath;
                if (IsAlreadyRegistered(context, relativePath))
                {
                    // A route for this file was already registered either by the CompiledPageRouteModel or as an area route.
                    // by this provider. Skip registering an additional entry.
                    continue;
                }

                if (!PageDirectiveFeature.TryGetPageDirective(_logger, item, out var routeTemplate))
                {
                    // .cshtml pages without @page are not RazorPages.
                    continue;
                }

                if (_pagesOptions.AllowAreas && relativePath.StartsWith(normalizedAreaRootDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    // Ignore Razor pages that are under the area root directory when AllowAreas is enabled.
                    // Conforming page paths will be added by AddAreaPageModels.
                    _logger.UnsupportedAreaPath(_pagesOptions, relativePath);
                    continue;
                }

                var routeModel = new PageRouteModel(relativePath, viewEnginePath: item.FilePathWithoutExtension);
                PageSelectorModel.PopulateDefaults(routeModel, routeModel.ViewEnginePath, routeTemplate);
                context.RouteModels.Add(routeModel);
            }
        }
        private void AddAreaPageModels(PageRouteModelProviderContext context)
        {
            foreach (var item in _project.EnumerateItems(_pagesOptions.AreaRootDirectory))
            {
                if (!IsRouteable(item))
                {
                    continue;
                }

                var relativePath = item.CombinedPath;
                if (IsAlreadyRegistered(context, relativePath))
                {
                    // A route for this file was already registered either by the CompiledPageRouteModel.
                    // Skip registering an additional entry.
                    continue;
                }

                if (!PageDirectiveFeature.TryGetPageDirective(_logger, item, out var routeTemplate))
                {
                    // .cshtml pages without @page are not RazorPages.
                    continue;
                }

                if (!PageSelectorModel.TryParseAreaPath(_pagesOptions, item.FilePath, _logger, out var areaResult))
                {
                    continue;
                }

                var routeModel = new PageRouteModel(relativePath, viewEnginePath: areaResult.viewEnginePath)
                {
                    RouteValues =
                    {
                        ["area"] = areaResult.areaName,
                    },
                };

                PageSelectorModel.PopulateDefaults(routeModel, areaResult.pageRoute, routeTemplate);
                context.RouteModels.Add(routeModel);
            }
        }