-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Update default Razor search paths to include ~/[PagesRoot]/Shared #6783
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 (_pagesOptions.Value.RootDirectory == "/") | ||
{ | ||
options.PageViewLocationFormats.Add("/{1}/{0}" + RazorViewEngine.ViewExtension); | ||
} | ||
else | ||
if (options == null) | ||
{ | ||
options.PageViewLocationFormats.Add(_pagesOptions.Value.RootDirectory + "/{1}/{0}" + RazorViewEngine.ViewExtension); | ||
throw new ArgumentNullException(nameof(options)); | ||
} | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait so we're making pages/shared searchable from views too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that's how @DamianEdwards wants this. The intent is to allow folks to migrate from Views -> Pages while keeping things working. |
||
|
||
options.ViewLocationExpanders.Add(new PageViewLocationExpander()); | ||
} | ||
|
||
private static string CombinePath(string path1, string path2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to preserve path separators (they are all meant to be forward slashes). |
||
{ | ||
if (path1.EndsWith("/", StringComparison.Ordinal)) | ||
{ | ||
return path1 + path2 + RazorViewEngine.ViewExtension; | ||
} | ||
|
||
return path1 + "/" + path2 + RazorViewEngine.ViewExtension; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since path1 is always There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what the check in line #47 does, no? |
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs two functional tests. (View -> Pages/Shared), (Page -> Pages/Shared) I don't think there's anywhere else in the system we unit test options setups 😆 |
||
{ | ||
[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; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@Html.Partial("_FileInShared) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
@page | ||
@Html.Partial("_FileInShared") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello from Pages/Shared |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@{ throw new Exception("This file should not be processed"); } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@{ throw new Exception("This file should not be processed"); } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello from Pages/Shared |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These shouldn't be asserts, they are clearly possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We disallow these in the property setter (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.RazorPages/RazorPagesOptions.cs#L32), but sure, we can throw for extra goodness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh ok, unimportant then