Remove root directory customization options for Razor Pages areas
Fixes #7608
This commit is contained in:
parent
62272ad56a
commit
9cea47fa7d
|
|
@ -117,12 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
rootDirectory = rootDirectory + "/";
|
rootDirectory = rootDirectory + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
var areaRootDirectory = _pagesOptions.AreaRootDirectory;
|
var areaRootDirectory = "/Areas/";
|
||||||
if (!areaRootDirectory.EndsWith("/", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
areaRootDirectory = areaRootDirectory + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var viewDescriptor in GetViewDescriptors(_applicationManager))
|
foreach (var viewDescriptor in GetViewDescriptors(_applicationManager))
|
||||||
{
|
{
|
||||||
if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_razorProjectEngine.FileSystem, viewDescriptor.Item))
|
if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_razorProjectEngine.FileSystem, viewDescriptor.Item))
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
|
|
@ -58,14 +57,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
if (razorPagesOptions.Value.AllowAreas)
|
if (razorPagesOptions.Value.AllowAreas)
|
||||||
{
|
{
|
||||||
var areaRootDirectory = razorPagesOptions.Value.AreaRootDirectory;
|
|
||||||
Debug.Assert(!string.IsNullOrEmpty(areaRootDirectory));
|
|
||||||
areaRootDirectory = areaRootDirectory.TrimEnd('/');
|
|
||||||
|
|
||||||
// Search pattern that matches all cshtml files under the Pages AreaRootDirectory
|
// Search pattern that matches all cshtml files under the Pages AreaRootDirectory
|
||||||
var areaRootSearchPattern = areaRootDirectory + "/**/*.cshtml";
|
var areaRootSearchPattern = "/Areas/**/*.cshtml";
|
||||||
|
|
||||||
var importFileAtAreaPagesRoot = areaRootDirectory + "/" + templateEngine.Options.ImportsFileName;
|
var importFileAtAreaPagesRoot = $"/Areas/{templateEngine.Options.ImportsFileName}";
|
||||||
var importPathsOutsideAreaPagesRoot = templateEngine.GetImportItems(importFileAtAreaPagesRoot)
|
var importPathsOutsideAreaPagesRoot = templateEngine.GetImportItems(importFileAtAreaPagesRoot)
|
||||||
.Select(item => item.FilePath);
|
.Select(item => item.FilePath);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
private static readonly Action<ILogger, string, string, Exception> _handlerMethodExecuted;
|
private static readonly Action<ILogger, string, string, Exception> _handlerMethodExecuted;
|
||||||
private static readonly Action<ILogger, object, Exception> _pageFilterShortCircuit;
|
private static readonly Action<ILogger, object, Exception> _pageFilterShortCircuit;
|
||||||
private static readonly Action<ILogger, string, string[], Exception> _malformedPageDirective;
|
private static readonly Action<ILogger, string, string[], Exception> _malformedPageDirective;
|
||||||
private static readonly Action<ILogger, string, string, string, string, Exception> _unsupportedAreaPath;
|
private static readonly Action<ILogger, string, Exception> _unsupportedAreaPath;
|
||||||
private static readonly Action<ILogger, Type, Exception> _notMostEffectiveFilter;
|
private static readonly Action<ILogger, Type, Exception> _notMostEffectiveFilter;
|
||||||
private static readonly Action<ILogger, string, string, string, Exception> _beforeExecutingMethodOnFilter;
|
private static readonly Action<ILogger, string, string, string, Exception> _beforeExecutingMethodOnFilter;
|
||||||
private static readonly Action<ILogger, string, string, string, Exception> _afterExecutingMethodOnFilter;
|
private static readonly Action<ILogger, string, string, string, Exception> _afterExecutingMethodOnFilter;
|
||||||
|
|
@ -63,10 +63,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
2,
|
2,
|
||||||
"{FilterType}: After executing {Method} on filter {Filter}.");
|
"{FilterType}: After executing {Method} on filter {Filter}.");
|
||||||
|
|
||||||
_unsupportedAreaPath = LoggerMessage.Define<string, string, string, string>(
|
_unsupportedAreaPath = LoggerMessage.Define<string>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
1,
|
1,
|
||||||
"The page at '{FilePath}' is located under the area root directory '{AreaRootDirectory}' but does not follow the path format '{AreaRootDirectory}{RootDirectory}/Directory/FileName.cshtml");
|
"The page at '{FilePath}' is located under the area root directory '/Areas/' but does not follow the path format '/Areas/AreaName/Pages/Directory/FileName.cshtml");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExecutingHandlerMethod(this ILogger logger, PageContext context, HandlerMethodDescriptor handler, object[] arguments)
|
public static void ExecutingHandlerMethod(this ILogger logger, PageContext context, HandlerMethodDescriptor handler, object[] arguments)
|
||||||
|
|
@ -140,11 +140,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_notMostEffectiveFilter(logger, policyType, null);
|
_notMostEffectiveFilter(logger, policyType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnsupportedAreaPath(this ILogger logger, RazorPagesOptions options, string filePath)
|
public static void UnsupportedAreaPath(this ILogger logger, string filePath)
|
||||||
{
|
{
|
||||||
if (logger.IsEnabled(LogLevel.Warning))
|
if (logger.IsEnabled(LogLevel.Warning))
|
||||||
{
|
{
|
||||||
_unsupportedAreaPath(logger, filePath, options.AreaRootDirectory, options.AreaRootDirectory, options.RootDirectory, null);
|
_unsupportedAreaPath(logger, filePath, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
|
||||||
_normalizedRootDirectory = NormalizeDirectory(options.RootDirectory);
|
_normalizedRootDirectory = NormalizeDirectory(options.RootDirectory);
|
||||||
_normalizedAreaRootDirectory = NormalizeDirectory(options.AreaRootDirectory);
|
_normalizedAreaRootDirectory = "/Areas/";
|
||||||
}
|
}
|
||||||
|
|
||||||
public PageRouteModel CreateRouteModel(string relativePath, string routeTemplate)
|
public PageRouteModel CreateRouteModel(string relativePath, string routeTemplate)
|
||||||
|
|
@ -86,6 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
// path = "/Areas/Products/Pages/Manage/Home.cshtml"
|
// path = "/Areas/Products/Pages/Manage/Home.cshtml"
|
||||||
// Result ("Products", "/Manage/Home")
|
// Result ("Products", "/Manage/Home")
|
||||||
|
const string AreaPagesRoot = "/Pages/";
|
||||||
|
|
||||||
result = default;
|
result = default;
|
||||||
Debug.Assert(relativePath.StartsWith("/", StringComparison.Ordinal));
|
Debug.Assert(relativePath.StartsWith("/", StringComparison.Ordinal));
|
||||||
|
|
@ -95,7 +96,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
areaRootEndIndex >= relativePath.Length - 1 || // There's at least one token after the area root.
|
areaRootEndIndex >= relativePath.Length - 1 || // There's at least one token after the area root.
|
||||||
!relativePath.StartsWith(_normalizedAreaRootDirectory, StringComparison.OrdinalIgnoreCase)) // The path must start with area root.
|
!relativePath.StartsWith(_normalizedAreaRootDirectory, StringComparison.OrdinalIgnoreCase)) // The path must start with area root.
|
||||||
{
|
{
|
||||||
_logger.UnsupportedAreaPath(_options, relativePath);
|
_logger.UnsupportedAreaPath(relativePath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,35 +104,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var areaEndIndex = relativePath.IndexOf('/', startIndex: areaRootEndIndex + 1);
|
var areaEndIndex = relativePath.IndexOf('/', startIndex: areaRootEndIndex + 1);
|
||||||
if (areaEndIndex == -1 || areaEndIndex == relativePath.Length)
|
if (areaEndIndex == -1 || areaEndIndex == relativePath.Length)
|
||||||
{
|
{
|
||||||
_logger.UnsupportedAreaPath(_options, relativePath);
|
_logger.UnsupportedAreaPath(relativePath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var areaName = relativePath.Substring(areaRootEndIndex + 1, areaEndIndex - areaRootEndIndex - 1);
|
var areaName = relativePath.Substring(areaRootEndIndex + 1, areaEndIndex - areaRootEndIndex - 1);
|
||||||
|
// Ensure the next token is the "Pages" directory
|
||||||
string viewEnginePath;
|
if (string.Compare(relativePath, areaEndIndex, AreaPagesRoot, 0, AreaPagesRoot.Length, StringComparison.OrdinalIgnoreCase) != 0)
|
||||||
if (_options.RootDirectory == "/")
|
|
||||||
{
|
{
|
||||||
// When RootDirectory is "/", every thing past the area name is the page path.
|
_logger.UnsupportedAreaPath(relativePath);
|
||||||
Debug.Assert(relativePath.EndsWith(RazorViewEngine.ViewExtension), $"{relativePath} does not end in extension '{RazorViewEngine.ViewExtension}'.");
|
return false;
|
||||||
viewEnginePath = relativePath.Substring(areaEndIndex, relativePath.Length - areaEndIndex - RazorViewEngine.ViewExtension.Length);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Normalize the pages root directory so that it has a trailing slash. This ensures we're looking at a directory delimiter
|
|
||||||
// and not just the area name occuring as part of a segment.
|
|
||||||
Debug.Assert(_options.RootDirectory.StartsWith("/", StringComparison.Ordinal));
|
|
||||||
// If the pages root has a value i.e. it's not the app root "/", ensure that the area path contains this value.
|
|
||||||
if (string.Compare(relativePath, areaEndIndex, _normalizedRootDirectory, 0, _normalizedRootDirectory.Length, StringComparison.OrdinalIgnoreCase) != 0)
|
|
||||||
{
|
|
||||||
_logger.UnsupportedAreaPath(_options, relativePath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include the trailing slash of the root directory at the start of the viewEnginePath
|
// Include the trailing slash of the root directory at the start of the viewEnginePath
|
||||||
var pageNameIndex = areaEndIndex + _normalizedRootDirectory.Length - 1;
|
var pageNameIndex = areaEndIndex + AreaPagesRoot.Length - 1;
|
||||||
viewEnginePath = relativePath.Substring(pageNameIndex, relativePath.Length - pageNameIndex - RazorViewEngine.ViewExtension.Length);
|
var viewEnginePath = relativePath.Substring(pageNameIndex, relativePath.Length - pageNameIndex - RazorViewEngine.ViewExtension.Length);
|
||||||
}
|
|
||||||
|
|
||||||
result = (areaName, viewEnginePath);
|
result = (areaName, viewEnginePath);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
options.PageViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
|
options.PageViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
|
||||||
|
|
||||||
Debug.Assert(!string.IsNullOrEmpty(_pagesOptions.AreaRootDirectory));
|
var areaDirectory = CombinePath("/Areas/", "{2}");
|
||||||
var areaDirectory = CombinePath(_pagesOptions.AreaRootDirectory, "{2}");
|
|
||||||
// Areas/{2}/Pages/
|
// Areas/{2}/Pages/
|
||||||
var areaPagesDirectory = CombinePath(areaDirectory, rootDirectory);
|
var areaPagesDirectory = CombinePath(areaDirectory, "/Pages/");
|
||||||
|
|
||||||
// Areas/{2}/Pages/{1}/{0}.cshtml
|
// Areas/{2}/Pages/{1}/{0}.cshtml
|
||||||
// Areas/{2}/Pages/Shared/{0}.cshtml
|
// Areas/{2}/Pages/Shared/{0}.cshtml
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
public class RazorProjectPageRouteModelProvider : IPageRouteModelProvider
|
public class RazorProjectPageRouteModelProvider : IPageRouteModelProvider
|
||||||
{
|
{
|
||||||
|
private const string AreaRootDirectory = "/Areas/";
|
||||||
private readonly RazorProjectFileSystem _razorFileSystem;
|
private readonly RazorProjectFileSystem _razorFileSystem;
|
||||||
private readonly RazorPagesOptions _pagesOptions;
|
private readonly RazorPagesOptions _pagesOptions;
|
||||||
private readonly PageRouteModelFactory _routeModelFactory;
|
private readonly PageRouteModelFactory _routeModelFactory;
|
||||||
|
|
@ -54,12 +55,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
private void AddPageModels(PageRouteModelProviderContext context)
|
private void AddPageModels(PageRouteModelProviderContext context)
|
||||||
{
|
{
|
||||||
var normalizedAreaRootDirectory = _pagesOptions.AreaRootDirectory;
|
|
||||||
if (!normalizedAreaRootDirectory.EndsWith("/", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
normalizedAreaRootDirectory += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in _razorFileSystem.EnumerateItems(_pagesOptions.RootDirectory))
|
foreach (var item in _razorFileSystem.EnumerateItems(_pagesOptions.RootDirectory))
|
||||||
{
|
{
|
||||||
if (!IsRouteable(item))
|
if (!IsRouteable(item))
|
||||||
|
|
@ -84,11 +79,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pagesOptions.AllowAreas && relativePath.StartsWith(normalizedAreaRootDirectory, StringComparison.OrdinalIgnoreCase))
|
if (_pagesOptions.AllowAreas && relativePath.StartsWith(AreaRootDirectory, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// Ignore Razor pages that are under the area root directory when AllowAreas is enabled.
|
// Ignore Razor pages that are under the area root directory when AllowAreas is enabled.
|
||||||
// Conforming page paths will be added by AddAreaPageModels.
|
// Conforming page paths will be added by AddAreaPageModels.
|
||||||
_logger.UnsupportedAreaPath(_pagesOptions, relativePath);
|
_logger.UnsupportedAreaPath(relativePath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
private void AddAreaPageModels(PageRouteModelProviderContext context)
|
private void AddAreaPageModels(PageRouteModelProviderContext context)
|
||||||
{
|
{
|
||||||
foreach (var item in _razorFileSystem.EnumerateItems(_pagesOptions.AreaRootDirectory))
|
foreach (var item in _razorFileSystem.EnumerateItems(AreaRootDirectory))
|
||||||
{
|
{
|
||||||
if (!IsRouteable(item))
|
if (!IsRouteable(item))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
private readonly ICompatibilitySwitch[] _switches;
|
private readonly ICompatibilitySwitch[] _switches;
|
||||||
|
|
||||||
private string _root = "/Pages";
|
private string _root = "/Pages";
|
||||||
private string _areasRoot = "/Areas";
|
|
||||||
|
|
||||||
public RazorPagesOptions()
|
public RazorPagesOptions()
|
||||||
{
|
{
|
||||||
|
|
@ -68,10 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// When enabled, any Razor Page under the directory structure <c>/{AreaRootDirectory}/AreaName/{RootDirectory}/</c>
|
/// When enabled, any Razor Page under the directory structure <c>/Area/AreaName/Pages/</c>
|
||||||
/// will be associated with an area with the name <c>AreaName</c>.
|
/// will be associated with an area with the name <c>AreaName</c>.
|
||||||
/// <seealso cref="AreaRootDirectory"/>
|
|
||||||
/// <seealso cref="RootDirectory"/>
|
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This property is associated with a compatibility switch and can provide a different behavior depending on
|
/// This property is associated with a compatibility switch and can provide a different behavior depending on
|
||||||
|
|
@ -137,30 +134,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
set => _allowMappingHeadRequestsToGetHandler.Value = value;
|
set => _allowMappingHeadRequestsToGetHandler.Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Application relative path used as the root of discovery for Razor Page files associated with areas.
|
|
||||||
/// Defaults to the <c>/Areas</c> directory under application root.
|
|
||||||
/// <seealso cref="AllowAreas" />
|
|
||||||
/// </summary>
|
|
||||||
public string AreaRootDirectory
|
|
||||||
{
|
|
||||||
get => _areasRoot;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value[0] != '/')
|
|
||||||
{
|
|
||||||
throw new ArgumentException(Resources.PathMustBeRootRelativePath, nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
_areasRoot = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator<ICompatibilitySwitch> IEnumerable<ICompatibilitySwitch>.GetEnumerator()
|
IEnumerator<ICompatibilitySwitch> IEnumerable<ICompatibilitySwitch>.GetEnumerator()
|
||||||
{
|
{
|
||||||
return ((IEnumerable<ICompatibilitySwitch>)_switches).GetEnumerator();
|
return ((IEnumerable<ICompatibilitySwitch>)_switches).GetEnumerator();
|
||||||
|
|
|
||||||
|
|
@ -214,15 +214,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
// Arrange
|
// Arrange
|
||||||
var descriptors = new[]
|
var descriptors = new[]
|
||||||
{
|
{
|
||||||
CreateVersion_2_0_Descriptor("/Features/Products/Files/About.cshtml"),
|
CreateVersion_2_0_Descriptor("/Areas/Products/Files/About.cshtml"),
|
||||||
CreateVersion_2_0_Descriptor("/Features/Products/Files/Manage/Index.cshtml"),
|
CreateVersion_2_0_Descriptor("/Areas/Products/Pages/About.cshtml"),
|
||||||
CreateVersion_2_0_Descriptor("/Features/Products/Files/Manage/Edit.cshtml", "{id}"),
|
CreateVersion_2_0_Descriptor("/Areas/Products/Pages/Manage/Index.cshtml"),
|
||||||
|
CreateVersion_2_0_Descriptor("/Areas/Products/Pages/Manage/Edit.cshtml", "{id}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
var options = new RazorPagesOptions
|
var options = new RazorPagesOptions
|
||||||
{
|
{
|
||||||
AllowAreas = true,
|
AllowAreas = true,
|
||||||
AreaRootDirectory = "/Features",
|
// Setting this value should not affect area page lookup.
|
||||||
RootDirectory = "/Files",
|
RootDirectory = "/Files",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -237,7 +238,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
context.RouteModels,
|
context.RouteModels,
|
||||||
result =>
|
result =>
|
||||||
{
|
{
|
||||||
Assert.Equal("/Features/Products/Files/About.cshtml", result.RelativePath);
|
Assert.Equal("/Areas/Products/Pages/About.cshtml", result.RelativePath);
|
||||||
Assert.Equal("/About", result.ViewEnginePath);
|
Assert.Equal("/About", result.ViewEnginePath);
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
result.Selectors,
|
result.Selectors,
|
||||||
|
|
@ -257,7 +258,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
},
|
},
|
||||||
result =>
|
result =>
|
||||||
{
|
{
|
||||||
Assert.Equal("/Features/Products/Files/Manage/Index.cshtml", result.RelativePath);
|
Assert.Equal("/Areas/Products/Pages/Manage/Index.cshtml", result.RelativePath);
|
||||||
Assert.Equal("/Manage/Index", result.ViewEnginePath);
|
Assert.Equal("/Manage/Index", result.ViewEnginePath);
|
||||||
Assert.Collection(result.Selectors,
|
Assert.Collection(result.Selectors,
|
||||||
selector => Assert.Equal("Products/Manage/Index", selector.AttributeRouteModel.Template),
|
selector => Assert.Equal("Products/Manage/Index", selector.AttributeRouteModel.Template),
|
||||||
|
|
@ -277,7 +278,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
},
|
},
|
||||||
result =>
|
result =>
|
||||||
{
|
{
|
||||||
Assert.Equal("/Features/Products/Files/Manage/Edit.cshtml", result.RelativePath);
|
Assert.Equal("/Areas/Products/Pages/Manage/Edit.cshtml", result.RelativePath);
|
||||||
Assert.Equal("/Manage/Edit", result.ViewEnginePath);
|
Assert.Equal("/Manage/Edit", result.ViewEnginePath);
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
result.Selectors,
|
result.Selectors,
|
||||||
|
|
@ -341,6 +342,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
// Arrange
|
// Arrange
|
||||||
var descriptors = new[]
|
var descriptors = new[]
|
||||||
{
|
{
|
||||||
|
CreateVersion_2_0_Descriptor("/Areas/Accounts/Pages/Manage/Home.cshtml"),
|
||||||
CreateVersion_2_0_Descriptor("/Areas/Accounts/Manage/Home.cshtml"),
|
CreateVersion_2_0_Descriptor("/Areas/Accounts/Manage/Home.cshtml"),
|
||||||
CreateVersion_2_0_Descriptor("/Areas/About.cshtml"),
|
CreateVersion_2_0_Descriptor("/Areas/About.cshtml"),
|
||||||
CreateVersion_2_0_Descriptor("/Contact.cshtml"),
|
CreateVersion_2_0_Descriptor("/Contact.cshtml"),
|
||||||
|
|
@ -349,7 +351,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var options = new RazorPagesOptions
|
var options = new RazorPagesOptions
|
||||||
{
|
{
|
||||||
AllowAreas = true,
|
AllowAreas = true,
|
||||||
AreaRootDirectory = "/Areas",
|
|
||||||
RootDirectory = "/",
|
RootDirectory = "/",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -364,7 +365,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
context.RouteModels,
|
context.RouteModels,
|
||||||
result =>
|
result =>
|
||||||
{
|
{
|
||||||
Assert.Equal("/Areas/Accounts/Manage/Home.cshtml", result.RelativePath);
|
Assert.Equal("/Areas/Accounts/Pages/Manage/Home.cshtml", result.RelativePath);
|
||||||
Assert.Equal("/Manage/Home", result.ViewEnginePath);
|
Assert.Equal("/Manage/Home", result.ViewEnginePath);
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
result.Selectors,
|
result.Selectors,
|
||||||
|
|
|
||||||
|
|
@ -87,34 +87,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
fileProvider.Verify(f => f.Watch("/Areas/**/*.cshtml"));
|
fileProvider.Verify(f => f.Watch("/Areas/**/*.cshtml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("/areas-base-dir")]
|
|
||||||
[InlineData("/areas-base-dir/")]
|
|
||||||
public void GetChangeToken_WatchesFilesUnderCustomAreaRoot(string rootDirectory)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var fileProvider = new Mock<IFileProvider>();
|
|
||||||
fileProvider.Setup(f => f.Watch(It.IsAny<string>()))
|
|
||||||
.Returns(Mock.Of<IChangeToken>());
|
|
||||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider.Object);
|
|
||||||
|
|
||||||
var templateEngine = new RazorTemplateEngine(
|
|
||||||
RazorEngine.Create(),
|
|
||||||
new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment));
|
|
||||||
var options = Options.Create(new RazorPagesOptions
|
|
||||||
{
|
|
||||||
AllowAreas = true,
|
|
||||||
AreaRootDirectory = rootDirectory,
|
|
||||||
});
|
|
||||||
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var changeToken = changeProvider.GetChangeToken();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
fileProvider.Verify(f => f.Watch("/areas-base-dir/**/*.cshtml"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetChangeToken_WatchesViewImportsOutsidePagesRoot_WhenPagesRootIsNested()
|
public void GetChangeToken_WatchesViewImportsOutsidePagesRoot_WhenPagesRootIsNested()
|
||||||
{
|
{
|
||||||
|
|
@ -140,7 +112,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetChangeToken_WatchesViewImportsOutsidePagesRoot_WhenAreaPagesRootIsNested()
|
public void GetChangeToken_WatchesViewImportsOutsidePagesRoot_WhenAllowAreasIsSpecified()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
|
|
@ -152,7 +124,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
|
templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
|
||||||
var options = Options.Create(new RazorPagesOptions());
|
var options = Options.Create(new RazorPagesOptions());
|
||||||
options.Value.RootDirectory = "/dir1/dir2";
|
options.Value.RootDirectory = "/dir1/dir2";
|
||||||
options.Value.AreaRootDirectory = "/dir3/dir4";
|
|
||||||
options.Value.AllowAreas = true;
|
options.Value.AllowAreas = true;
|
||||||
|
|
||||||
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
|
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
|
||||||
|
|
@ -162,9 +133,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Collection(compositeChangeToken.ChangeTokens,
|
Assert.Collection(compositeChangeToken.ChangeTokens,
|
||||||
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir1/_ViewImports.cshtml"), changeToken),
|
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir1/_ViewImports.cshtml"), changeToken),
|
||||||
changeToken => Assert.Same(fileProvider.GetChangeToken("/_ViewImports.cshtml"), changeToken),
|
changeToken => Assert.Same(fileProvider.GetChangeToken("/_ViewImports.cshtml"), changeToken),
|
||||||
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir3/_ViewImports.cshtml"), changeToken),
|
|
||||||
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir1/dir2/**/*.cshtml"), changeToken),
|
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir1/dir2/**/*.cshtml"), changeToken),
|
||||||
changeToken => Assert.Same(fileProvider.GetChangeToken("/dir3/dir4/**/*.cshtml"), changeToken));
|
changeToken => Assert.Same(fileProvider.GetChangeToken("/Areas/**/*.cshtml"), changeToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -221,30 +221,5 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Equal(expectedArea, result.areaName);
|
Assert.Equal(expectedArea, result.areaName);
|
||||||
Assert.Equal(expectedViewEnginePath, result.viewEnginePath);
|
Assert.Equal(expectedViewEnginePath, result.viewEnginePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
|
||||||
[FrameworkSkipCondition(RuntimeFrameworks.CLR, SkipReason = "Fails due to dotnet/standard#567")]
|
|
||||||
[InlineData("/Areas/MyArea/Dir1/Dir2/Index.cshtml", "MyArea", "/Index")]
|
|
||||||
[InlineData("/Areas/Accounts/Dir1/Dir2/Manage/Edit.cshtml", "Accounts", "/Manage/Edit")]
|
|
||||||
public void TryParseAreaPath_ParsesAreaPath_WithMultiLevelRootDirectory(
|
|
||||||
string path,
|
|
||||||
string expectedArea,
|
|
||||||
string expectedViewEnginePath)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var options = new RazorPagesOptions
|
|
||||||
{
|
|
||||||
RootDirectory = "/Dir1/Dir2"
|
|
||||||
};
|
|
||||||
var routeModelFactory = new PageRouteModelFactory(options, NullLogger.Instance);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var success = routeModelFactory.TryParseAreaPath(path, out var result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.True(success);
|
|
||||||
Assert.Equal(expectedArea, result.areaName);
|
|
||||||
Assert.Equal(expectedViewEnginePath, result.viewEnginePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,21 +88,20 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Configure_WithCustomRoots_AddsAreaPageViewLocationFormats()
|
public void Configure_WithCustomRoot_AddsAreaPageViewLocationFormats()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[]
|
var expected = new[]
|
||||||
{
|
{
|
||||||
"/Features/{2}/RazorFiles/{1}/{0}.cshtml",
|
"/Areas/{2}/Pages/{1}/{0}.cshtml",
|
||||||
"/Features/{2}/RazorFiles/Shared/{0}.cshtml",
|
"/Areas/{2}/Pages/Shared/{0}.cshtml",
|
||||||
"/Features/{2}/Views/Shared/{0}.cshtml",
|
"/Areas/{2}/Views/Shared/{0}.cshtml",
|
||||||
"/RazorFiles/Shared/{0}.cshtml",
|
"/RazorFiles/Shared/{0}.cshtml",
|
||||||
"/Views/Shared/{0}.cshtml",
|
"/Views/Shared/{0}.cshtml",
|
||||||
};
|
};
|
||||||
|
|
||||||
var razorPagesOptions = new RazorPagesOptions
|
var razorPagesOptions = new RazorPagesOptions
|
||||||
{
|
{
|
||||||
AreaRootDirectory = "/Features",
|
|
||||||
RootDirectory = "/RazorFiles/",
|
RootDirectory = "/RazorFiles/",
|
||||||
};
|
};
|
||||||
var viewEngineOptions = GetViewEngineOptions();
|
var viewEngineOptions = GetViewEngineOptions();
|
||||||
|
|
|
||||||
|
|
@ -155,15 +155,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Categories.cshtml", "@page"));
|
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/Categories.cshtml", "@page"));
|
||||||
// We shouldn't add a route for this.
|
|
||||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Home.cshtml", "@page"));
|
|
||||||
fileSystem.Add(new TestRazorProjectItem("/About.cshtml", "@page"));
|
fileSystem.Add(new TestRazorProjectItem("/About.cshtml", "@page"));
|
||||||
|
// We shouldn't add a route for the following paths.
|
||||||
|
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Categories.cshtml", "@page"));
|
||||||
|
fileSystem.Add(new TestRazorProjectItem("/Areas/Home.cshtml", "@page"));
|
||||||
|
|
||||||
var optionsManager = Options.Create(new RazorPagesOptions
|
var optionsManager = Options.Create(new RazorPagesOptions
|
||||||
{
|
{
|
||||||
RootDirectory = "/",
|
RootDirectory = "/",
|
||||||
AreaRootDirectory = "/Areas",
|
|
||||||
AllowAreas = true,
|
AllowAreas = true,
|
||||||
});
|
});
|
||||||
var provider = new RazorProjectPageRouteModelProvider(fileSystem, optionsManager, NullLoggerFactory.Instance);
|
var provider = new RazorProjectPageRouteModelProvider(fileSystem, optionsManager, NullLoggerFactory.Instance);
|
||||||
|
|
@ -176,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Collection(context.RouteModels,
|
Assert.Collection(context.RouteModels,
|
||||||
model =>
|
model =>
|
||||||
{
|
{
|
||||||
Assert.Equal("/Areas/Products/Categories.cshtml", model.RelativePath);
|
Assert.Equal("/Areas/Products/Pages/Categories.cshtml", model.RelativePath);
|
||||||
Assert.Equal("/Categories", model.ViewEnginePath);
|
Assert.Equal("/Categories", model.ViewEnginePath);
|
||||||
Assert.Collection(model.Selectors,
|
Assert.Collection(model.Selectors,
|
||||||
selector => Assert.Equal("Products/Categories", selector.AttributeRouteModel.Template));
|
selector => Assert.Equal("Products/Categories", selector.AttributeRouteModel.Template));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue