_ViewStart.cshtml not picked up when added to the root of the app

Fixes #6308
This commit is contained in:
Pranav K 2017-06-22 15:29:52 -07:00
parent 0dfffd45c2
commit aa5a348385
5 changed files with 36 additions and 78 deletions

View File

@ -37,7 +37,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
private readonly IModelMetadataProvider _modelMetadataProvider;
private readonly ITempDataDictionaryFactory _tempDataFactory;
private readonly HtmlHelperOptions _htmlHelperOptions;
private readonly RazorPagesOptions _razorPagesOptions;
private readonly IPageHandlerMethodSelector _selector;
private readonly RazorProject _razorProject;
private readonly DiagnosticSource _diagnosticSource;
@ -56,7 +55,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
ITempDataDictionaryFactory tempDataFactory,
IOptions<MvcOptions> mvcOptions,
IOptions<HtmlHelperOptions> htmlHelperOptions,
IOptions<RazorPagesOptions> razorPagesOptions,
IPageHandlerMethodSelector selector,
RazorProject razorProject,
DiagnosticSource diagnosticSource,
@ -73,7 +71,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
_modelMetadataProvider = modelMetadataProvider;
_tempDataFactory = tempDataFactory;
_htmlHelperOptions = htmlHelperOptions.Value;
_razorPagesOptions = razorPagesOptions.Value;
_selector = selector;
_razorProject = razorProject;
_diagnosticSource = diagnosticSource;
@ -210,8 +207,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
internal List<Func<IRazorPage>> GetViewStartFactories(CompiledPageActionDescriptor descriptor)
{
var viewStartFactories = new List<Func<IRazorPage>>();
// Always pick up all _ViewStarts, including the ones outside the Pages root.
var viewStartItems = _razorProject.FindHierarchicalItems(
_razorPagesOptions.RootDirectory,
descriptor.RelativePath,
ViewStartFileName);
foreach (var item in viewStartItems)

View File

@ -129,6 +129,20 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
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]
public async Task ViewImport_IsDiscoveredWhenRootDirectoryIsSpecified()
{

View File

@ -196,8 +196,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
loader.Object,
CreateActionDescriptorCollection(descriptor),
razorPageFactoryProvider: razorPageFactoryProvider.Object,
razorProject: defaultRazorProject,
razorPagesOptions: new RazorPagesOptions { RootDirectory = "/" });
razorProject: defaultRazorProject);
var context = new ActionInvokerProviderContext(new ActionContext()
{
@ -317,67 +316,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
[Fact]
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
var descriptor = new PageActionDescriptor()
{
@ -414,19 +353,22 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
.Setup(p => p.CreateFactory("/Pages/Level1/_ViewStart.cshtml"))
.Returns(new RazorPageFactoryResult(() => null, new List<IChangeToken>()))
.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
{
RootDirectory = rootDirectory,
};
var razorPageFactoryProvider = mock.Object;
var invokerProvider = CreateInvokerProvider(
loader.Object,
CreateActionDescriptorCollection(descriptor),
razorPageFactoryProvider: razorPageFactoryProvider,
razorProject: razorProject,
razorPagesOptions: options);
razorProject: razorProject);
// Act
var factories = invokerProvider.GetViewStartFactories(compiledPageDescriptor);
@ -474,8 +416,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
pageProvider: null,
modelProvider: null,
razorPageFactoryProvider: pageFactory.Object,
razorProject: razorProject,
razorPagesOptions: new RazorPagesOptions { RootDirectory = "/" });
razorProject: razorProject);
var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor);
@ -513,8 +454,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
IPageFactoryProvider pageProvider = null,
IPageModelFactoryProvider modelProvider = null,
IRazorPageFactoryProvider razorPageFactoryProvider = null,
RazorProject razorProject = null,
RazorPagesOptions razorPagesOptions = null)
RazorProject razorProject = null)
{
var tempDataFactory = new Mock<ITempDataDictionaryFactory>();
tempDataFactory
@ -544,7 +484,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
tempDataFactory.Object,
new TestOptionsManager<MvcOptions>(),
new TestOptionsManager<HtmlHelperOptions>(),
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions ?? new RazorPagesOptions()),
Mock.Of<IPageHandlerMethodSelector>(),
razorProject,
new DiagnosticListener("Microsoft.AspNetCore"),

View File

@ -0,0 +1,2 @@
@page
Hello from page

View File

@ -0,0 +1,6 @@
@using Microsoft.AspNetCore.Mvc.RazorPages
@if (((PageActionDescriptor)ViewContext.ActionDescriptor).ViewEnginePath == "/WithViewStart/ViewStartAtRoot")
{
<text>Hello from _ViewStart at root
</text>
}