Update default Razor search paths to include ~/[PagesRoot]/Shared

Fixes #6604
This commit is contained in:
Pranav K 2017-09-07 12:51:38 -07:00
parent a8b7904b00
commit 6bf165f22f
14 changed files with 208 additions and 11 deletions

View File

@ -113,6 +113,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
/// /Pages/Account/{0}.cshtml
/// /Pages/{0}.cshtml
/// /Views/Shared/{0}.cshtml
/// /Pages/Shared/{0}.cshtml
/// </para>
/// </remarks>
public IList<string> PageViewLocationFormats { get; } = new List<string>();

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
@ -10,29 +11,45 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{
public class RazorPagesRazorViewEngineOptionsSetup : IConfigureOptions<RazorViewEngineOptions>
{
private readonly IOptions<RazorPagesOptions> _pagesOptions;
private readonly RazorPagesOptions _pagesOptions;
public RazorPagesRazorViewEngineOptionsSetup(IOptions<RazorPagesOptions> pagesOptions)
{
_pagesOptions = pagesOptions;
_pagesOptions = pagesOptions?.Value ?? throw new ArgumentNullException(nameof(pagesOptions));
}
public void Configure(RazorViewEngineOptions options)
{
Debug.Assert(_pagesOptions.Value.RootDirectory.Length > 0);
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
if (_pagesOptions.Value.RootDirectory == "/")
{
options.PageViewLocationFormats.Add("/{1}/{0}" + RazorViewEngine.ViewExtension);
}
else
{
options.PageViewLocationFormats.Add(_pagesOptions.Value.RootDirectory + "/{1}/{0}" + RazorViewEngine.ViewExtension);
}
var rootDirectory = _pagesOptions.RootDirectory;
Debug.Assert(!string.IsNullOrEmpty(rootDirectory));
var defaultPageSearchPath = CombinePath(rootDirectory, "{1}/{0}");
options.PageViewLocationFormats.Add(defaultPageSearchPath);
// /Pages/Shared/{0}.cshtml
var pagesSharedDirectory = CombinePath(rootDirectory, "Shared/{0}");
options.PageViewLocationFormats.Add(pagesSharedDirectory);
options.PageViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.ViewLocationFormats.Add(pagesSharedDirectory);
options.AreaViewLocationFormats.Add(pagesSharedDirectory);
options.ViewLocationExpanders.Add(new PageViewLocationExpander());
}
private static string CombinePath(string path1, string path2)
{
if (path1.EndsWith("/", StringComparison.Ordinal))
{
return path1 + path2 + RazorViewEngine.ViewExtension;
}
return path1 + "/" + path2 + RazorViewEngine.ViewExtension;
}
}
}

View File

@ -274,5 +274,18 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(expected, response.Trim());
}
[Fact]
public async Task Pages_ReturnsFromPagesSharedDirectory()
{
// Arrange
var expected = "Hello from Pages/Shared";
// Act
var response = await Client.GetStringAsync("/SearchInPages");
// Assert
Assert.Equal(expected, response.Trim());
}
}
}

View File

@ -513,5 +513,18 @@ Partial";
// Assert
Assert.Equal(expected, responseContent.Trim());
}
[Fact]
public async Task ViewEngine_DiscoversViewsFromPagesSharedDirectory()
{
// Arrange
var expected = "Hello from Pages/Shared";
// Act
var responseContent = await Client.GetStringAsync("/ViewEngine/SearchInPages");
// Assert
Assert.Equal(expected, responseContent.Trim());
}
}
}

View File

@ -1990,6 +1990,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
var options = new RazorViewEngineOptions();
optionsSetup.Configure(options);
options.PageViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
options.PageViewLocationFormats.Add("/Pages/Shared/{0}.cshtml");
if (expanders != null)
{

View File

@ -0,0 +1,142 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{
public class RazorPagesRazorViewEngineOptionsSetupTest
{
[Fact]
public void Configure_AddsPageViewLocationFormats_WhenPagesRootIsAppRoot()
{
// Arrange
var expected = new[]
{
"/{1}/{0}.cshtml",
"/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml",
};
var razorPagesOptions = new RazorPagesOptions
{
RootDirectory = "/"
};
var viewEngineOptions = GetViewEngineOptions();
var setup = new RazorPagesRazorViewEngineOptionsSetup(
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions));
// Act
setup.Configure(viewEngineOptions);
// Assert
Assert.Equal(expected, viewEngineOptions.PageViewLocationFormats);
}
[Fact]
public void Configure_AddsPageViewLocationFormats_WithDefaultPagesRoot()
{
// Arrange
var expected = new[]
{
"/Pages/{1}/{0}.cshtml",
"/Pages/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml",
};
var razorPagesOptions = new RazorPagesOptions();
var viewEngineOptions = GetViewEngineOptions();
var setup = new RazorPagesRazorViewEngineOptionsSetup(
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions));
// Act
setup.Configure(viewEngineOptions);
// Assert
Assert.Equal(expected, viewEngineOptions.PageViewLocationFormats);
}
[Fact]
public void Configure_AddsSharedPagesDirectoryToViewLocationFormats()
{
// Arrange
var expected = new[]
{
"/Views/{1}/{0}.cshtml",
"/Views/Shared/{0}.cshtml",
"/PagesRoot/Shared/{0}.cshtml",
};
var razorPagesOptions = new RazorPagesOptions
{
RootDirectory = "/PagesRoot",
};
var viewEngineOptions = GetViewEngineOptions();
var setup = new RazorPagesRazorViewEngineOptionsSetup(
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions));
// Act
setup.Configure(viewEngineOptions);
// Assert
Assert.Equal(expected, viewEngineOptions.ViewLocationFormats);
}
[Fact]
public void Configure_AddsSharedPagesDirectoryToAreaViewLocationFormats()
{
// Arrange
var expected = new[]
{
"/Areas/{2}/Views/{1}/{0}.cshtml",
"/Areas/{2}/Views/Shared/{0}.cshtml",
"/Views/Shared/{0}.cshtml",
"/PagesRoot/Shared/{0}.cshtml",
};
var razorPagesOptions = new RazorPagesOptions
{
RootDirectory = "/PagesRoot",
};
var viewEngineOptions = GetViewEngineOptions();
var setup = new RazorPagesRazorViewEngineOptionsSetup(
new TestOptionsManager<RazorPagesOptions>(razorPagesOptions));
// Act
setup.Configure(viewEngineOptions);
// Assert
Assert.Equal(expected, viewEngineOptions.AreaViewLocationFormats);
}
[Fact]
public void Configure_RegistersPageViewLocationExpander()
{
// Arrange
var viewEngineOptions = GetViewEngineOptions();
var setup = new RazorPagesRazorViewEngineOptionsSetup(new TestOptionsManager<RazorPagesOptions>());
// Act
setup.Configure(viewEngineOptions);
// Assert
Assert.Collection(
viewEngineOptions.ViewLocationExpanders,
expander => Assert.IsType<PageViewLocationExpander>(expander));
}
private static RazorViewEngineOptions GetViewEngineOptions()
{
var defaultSetup = new RazorViewEngineOptionsSetup(Mock.Of<IHostingEnvironment>());
var options = new RazorViewEngineOptions();
defaultSetup.Configure(options);
return options;
}
}
}

View File

@ -0,0 +1 @@
@Html.Partial("_FileInShared)

View File

@ -0,0 +1,2 @@
@page
@Html.Partial("_FileInShared")

View File

@ -0,0 +1 @@
Hello from Pages/Shared

View File

@ -0,0 +1 @@
@{ throw new Exception("This file should not be processed"); }

View File

@ -77,5 +77,7 @@ namespace RazorWebSite.Controllers
{
return View();
}
public IActionResult SearchInPages() => View();
}
}

View File

@ -0,0 +1 @@
@{ throw new Exception("This file should not be processed"); }

View File

@ -0,0 +1 @@
Hello from Pages/Shared

View File

@ -0,0 +1 @@
@Html.Partial("_SharedFromPages")