_ViewStart.cshtml not picked up when added to the root of the app
Fixes #6308
This commit is contained in:
parent
0dfffd45c2
commit
aa5a348385
|
|
@ -37,7 +37,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
private readonly IModelMetadataProvider _modelMetadataProvider;
|
private readonly IModelMetadataProvider _modelMetadataProvider;
|
||||||
private readonly ITempDataDictionaryFactory _tempDataFactory;
|
private readonly ITempDataDictionaryFactory _tempDataFactory;
|
||||||
private readonly HtmlHelperOptions _htmlHelperOptions;
|
private readonly HtmlHelperOptions _htmlHelperOptions;
|
||||||
private readonly RazorPagesOptions _razorPagesOptions;
|
|
||||||
private readonly IPageHandlerMethodSelector _selector;
|
private readonly IPageHandlerMethodSelector _selector;
|
||||||
private readonly RazorProject _razorProject;
|
private readonly RazorProject _razorProject;
|
||||||
private readonly DiagnosticSource _diagnosticSource;
|
private readonly DiagnosticSource _diagnosticSource;
|
||||||
|
|
@ -56,7 +55,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
ITempDataDictionaryFactory tempDataFactory,
|
ITempDataDictionaryFactory tempDataFactory,
|
||||||
IOptions<MvcOptions> mvcOptions,
|
IOptions<MvcOptions> mvcOptions,
|
||||||
IOptions<HtmlHelperOptions> htmlHelperOptions,
|
IOptions<HtmlHelperOptions> htmlHelperOptions,
|
||||||
IOptions<RazorPagesOptions> razorPagesOptions,
|
|
||||||
IPageHandlerMethodSelector selector,
|
IPageHandlerMethodSelector selector,
|
||||||
RazorProject razorProject,
|
RazorProject razorProject,
|
||||||
DiagnosticSource diagnosticSource,
|
DiagnosticSource diagnosticSource,
|
||||||
|
|
@ -73,7 +71,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_modelMetadataProvider = modelMetadataProvider;
|
_modelMetadataProvider = modelMetadataProvider;
|
||||||
_tempDataFactory = tempDataFactory;
|
_tempDataFactory = tempDataFactory;
|
||||||
_htmlHelperOptions = htmlHelperOptions.Value;
|
_htmlHelperOptions = htmlHelperOptions.Value;
|
||||||
_razorPagesOptions = razorPagesOptions.Value;
|
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
_razorProject = razorProject;
|
_razorProject = razorProject;
|
||||||
_diagnosticSource = diagnosticSource;
|
_diagnosticSource = diagnosticSource;
|
||||||
|
|
@ -210,8 +207,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
internal List<Func<IRazorPage>> GetViewStartFactories(CompiledPageActionDescriptor descriptor)
|
internal List<Func<IRazorPage>> GetViewStartFactories(CompiledPageActionDescriptor descriptor)
|
||||||
{
|
{
|
||||||
var viewStartFactories = new List<Func<IRazorPage>>();
|
var viewStartFactories = new List<Func<IRazorPage>>();
|
||||||
|
// Always pick up all _ViewStarts, including the ones outside the Pages root.
|
||||||
var viewStartItems = _razorProject.FindHierarchicalItems(
|
var viewStartItems = _razorProject.FindHierarchicalItems(
|
||||||
_razorPagesOptions.RootDirectory,
|
|
||||||
descriptor.RelativePath,
|
descriptor.RelativePath,
|
||||||
ViewStartFileName);
|
ViewStartFileName);
|
||||||
foreach (var item in viewStartItems)
|
foreach (var item in viewStartItems)
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,20 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.Equal(expected, response.Trim());
|
Assert.Equal(expected, response.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ViewStart_IsDiscoveredForFilesOutsidePageRoot()
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var newLine = Environment.NewLine;
|
||||||
|
var expected = $"Hello from _ViewStart at root{newLine}Hello from _ViewStart{newLine}Hello from page";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await Client.GetStringAsync("/WithViewStart/ViewStartAtRoot");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, response.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ViewImport_IsDiscoveredWhenRootDirectoryIsSpecified()
|
public async Task ViewImport_IsDiscoveredWhenRootDirectoryIsSpecified()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -196,8 +196,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
loader.Object,
|
loader.Object,
|
||||||
CreateActionDescriptorCollection(descriptor),
|
CreateActionDescriptorCollection(descriptor),
|
||||||
razorPageFactoryProvider: razorPageFactoryProvider.Object,
|
razorPageFactoryProvider: razorPageFactoryProvider.Object,
|
||||||
razorProject: defaultRazorProject,
|
razorProject: defaultRazorProject);
|
||||||
razorPagesOptions: new RazorPagesOptions { RootDirectory = "/" });
|
|
||||||
|
|
||||||
var context = new ActionInvokerProviderContext(new ActionContext()
|
var context = new ActionInvokerProviderContext(new ActionContext()
|
||||||
{
|
{
|
||||||
|
|
@ -317,67 +316,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetViewStartFactories_FindsFullHeirarchy()
|
public void GetViewStartFactories_FindsFullHeirarchy()
|
||||||
{
|
{
|
||||||
// Arrange
|
|
||||||
var descriptor = new PageActionDescriptor()
|
|
||||||
{
|
|
||||||
RelativePath = "/Views/Deeper/Index.cshtml",
|
|
||||||
FilterDescriptors = new FilterDescriptor[0],
|
|
||||||
ViewEnginePath = "/Views/Deeper/Index.cshtml"
|
|
||||||
};
|
|
||||||
|
|
||||||
var loader = new Mock<IPageLoader>();
|
|
||||||
loader
|
|
||||||
.Setup(l => l.Load(It.IsAny<PageActionDescriptor>()))
|
|
||||||
.Returns(CreateCompiledPageActionDescriptor(descriptor, typeof(TestPageModel)));
|
|
||||||
|
|
||||||
var fileProvider = new TestFileProvider();
|
|
||||||
fileProvider.AddFile("/View/Deeper/Not_ViewStart.cshtml", "page content");
|
|
||||||
fileProvider.AddFile("/View/Wrong/_ViewStart.cshtml", "page content");
|
|
||||||
fileProvider.AddFile("/_ViewStart.cshtml", "page content ");
|
|
||||||
fileProvider.AddFile("/Views/_ViewStart.cshtml", "@page starts!");
|
|
||||||
fileProvider.AddFile("/Views/Deeper/_ViewStart.cshtml", "page content");
|
|
||||||
|
|
||||||
var razorProject = new TestRazorProject(fileProvider);
|
|
||||||
|
|
||||||
var mock = new Mock<IRazorPageFactoryProvider>();
|
|
||||||
mock
|
|
||||||
.Setup(p => p.CreateFactory("/Views/Deeper/_ViewStart.cshtml"))
|
|
||||||
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
|
||||||
.Verifiable();
|
|
||||||
mock
|
|
||||||
.Setup(p => p.CreateFactory("/Views/_ViewStart.cshtml"))
|
|
||||||
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
|
||||||
.Verifiable();
|
|
||||||
mock
|
|
||||||
.Setup(p => p.CreateFactory("/_ViewStart.cshtml"))
|
|
||||||
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
|
||||||
.Verifiable();
|
|
||||||
|
|
||||||
var razorPageFactoryProvider = mock.Object;
|
|
||||||
|
|
||||||
var invokerProvider = CreateInvokerProvider(
|
|
||||||
loader.Object,
|
|
||||||
CreateActionDescriptorCollection(descriptor),
|
|
||||||
pageProvider: null,
|
|
||||||
modelProvider: null,
|
|
||||||
razorPageFactoryProvider: razorPageFactoryProvider,
|
|
||||||
razorProject: razorProject,
|
|
||||||
razorPagesOptions: new RazorPagesOptions { RootDirectory = "/" });
|
|
||||||
|
|
||||||
var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var factories = invokerProvider.GetViewStartFactories(compiledDescriptor);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
mock.Verify();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("/Pages/Level1/")]
|
|
||||||
[InlineData("/Pages/Level1")]
|
|
||||||
public void GetPageFactories_DoesNotFindViewStartsOutsideBaseDirectory(string rootDirectory)
|
|
||||||
{
|
|
||||||
// Arrange
|
// Arrange
|
||||||
var descriptor = new PageActionDescriptor()
|
var descriptor = new PageActionDescriptor()
|
||||||
{
|
{
|
||||||
|
|
@ -414,19 +353,22 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
.Setup(p => p.CreateFactory("/Pages/Level1/_ViewStart.cshtml"))
|
.Setup(p => p.CreateFactory("/Pages/Level1/_ViewStart.cshtml"))
|
||||||
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var razorPageFactoryProvider = mock.Object;
|
mock
|
||||||
|
.Setup(p => p.CreateFactory("/Pages/_ViewStart.cshtml"))
|
||||||
|
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
||||||
|
.Verifiable();
|
||||||
|
mock
|
||||||
|
.Setup(p => p.CreateFactory("/_ViewStart.cshtml"))
|
||||||
|
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
var options = new RazorPagesOptions
|
var razorPageFactoryProvider = mock.Object;
|
||||||
{
|
|
||||||
RootDirectory = rootDirectory,
|
|
||||||
};
|
|
||||||
|
|
||||||
var invokerProvider = CreateInvokerProvider(
|
var invokerProvider = CreateInvokerProvider(
|
||||||
loader.Object,
|
loader.Object,
|
||||||
CreateActionDescriptorCollection(descriptor),
|
CreateActionDescriptorCollection(descriptor),
|
||||||
razorPageFactoryProvider: razorPageFactoryProvider,
|
razorPageFactoryProvider: razorPageFactoryProvider,
|
||||||
razorProject: razorProject,
|
razorProject: razorProject);
|
||||||
razorPagesOptions: options);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factories = invokerProvider.GetViewStartFactories(compiledPageDescriptor);
|
var factories = invokerProvider.GetViewStartFactories(compiledPageDescriptor);
|
||||||
|
|
@ -474,8 +416,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
pageProvider: null,
|
pageProvider: null,
|
||||||
modelProvider: null,
|
modelProvider: null,
|
||||||
razorPageFactoryProvider: pageFactory.Object,
|
razorPageFactoryProvider: pageFactory.Object,
|
||||||
razorProject: razorProject,
|
razorProject: razorProject);
|
||||||
razorPagesOptions: new RazorPagesOptions { RootDirectory = "/" });
|
|
||||||
|
|
||||||
var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor);
|
var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor);
|
||||||
|
|
||||||
|
|
@ -513,8 +454,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
IPageFactoryProvider pageProvider = null,
|
IPageFactoryProvider pageProvider = null,
|
||||||
IPageModelFactoryProvider modelProvider = null,
|
IPageModelFactoryProvider modelProvider = null,
|
||||||
IRazorPageFactoryProvider razorPageFactoryProvider = null,
|
IRazorPageFactoryProvider razorPageFactoryProvider = null,
|
||||||
RazorProject razorProject = null,
|
RazorProject razorProject = null)
|
||||||
RazorPagesOptions razorPagesOptions = null)
|
|
||||||
{
|
{
|
||||||
var tempDataFactory = new Mock<ITempDataDictionaryFactory>();
|
var tempDataFactory = new Mock<ITempDataDictionaryFactory>();
|
||||||
tempDataFactory
|
tempDataFactory
|
||||||
|
|
@ -544,7 +484,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
tempDataFactory.Object,
|
tempDataFactory.Object,
|
||||||
new TestOptionsManager<MvcOptions>(),
|
new TestOptionsManager<MvcOptions>(),
|
||||||
new TestOptionsManager<HtmlHelperOptions>(),
|
new TestOptionsManager<HtmlHelperOptions>(),
|
||||||
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions ?? new RazorPagesOptions()),
|
|
||||||
Mock.Of<IPageHandlerMethodSelector>(),
|
Mock.Of<IPageHandlerMethodSelector>(),
|
||||||
razorProject,
|
razorProject,
|
||||||
new DiagnosticListener("Microsoft.AspNetCore"),
|
new DiagnosticListener("Microsoft.AspNetCore"),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
@page
|
||||||
|
Hello from page
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
@using Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
|
@if (((PageActionDescriptor)ViewContext.ActionDescriptor).ViewEnginePath == "/WithViewStart/ViewStartAtRoot")
|
||||||
|
{
|
||||||
|
<text>Hello from _ViewStart at root
|
||||||
|
</text>
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue