Updated Razor Pages areas for compatibility switches

This commit is contained in:
Ryan Nowak 2018-01-01 19:13:43 -08:00
parent 64a11e2093
commit 49bdcfb150
12 changed files with 117 additions and 20 deletions

View File

@ -51,9 +51,8 @@ namespace Microsoft.AspNetCore.Mvc
/// <remarks> /// <remarks>
/// ASP.NET Core MVC 2.1 introduces compatibility switches for the following: /// ASP.NET Core MVC 2.1 introduces compatibility switches for the following:
/// <list type="bullet"> /// <list type="bullet">
/// <item> /// <item><description><see cref="MvcOptions.SuppressBindingUndefinedValueToEnumType"/></description></item>
/// <description><see cref="MvcOptions.SuppressBindingUndefinedValueToEnumType"/></description> /// <item><description><c>RazorPagesOptions.AllowAreas</c></description></item>
/// </item>
/// </list> /// </list>
/// </remarks> /// </remarks>
Version_2_1, Version_2_1,

View File

@ -81,6 +81,8 @@ namespace Microsoft.Extensions.DependencyInjection
// Options // Options
services.TryAddEnumerable( services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorPagesRazorViewEngineOptionsSetup>()); ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorPagesRazorViewEngineOptionsSetup>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IPostConfigureOptions<RazorPagesOptions>, RazorPagesOptionsConfigureCompatibilityOptions>());
// Action description and invocation // Action description and invocation
services.TryAddEnumerable( services.TryAddEnumerable(

View File

@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{ {
model = GetPageRouteModel(rootDirectory, viewDescriptor); model = GetPageRouteModel(rootDirectory, viewDescriptor);
} }
else if (_pagesOptions.EnableAreas && viewDescriptor.RelativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase)) else if (_pagesOptions.AllowAreas && viewDescriptor.RelativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase))
{ {
model = GetAreaPageRouteModel(areaRootDirectory, viewDescriptor); model = GetAreaPageRouteModel(areaRootDirectory, viewDescriptor);
} }

View File

@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
var additionalImportFilePaths = templateEngine.GetImportItems(importFileAtPagesRoot) var additionalImportFilePaths = templateEngine.GetImportItems(importFileAtPagesRoot)
.Select(item => item.FilePath); .Select(item => item.FilePath);
if (razorPagesOptions.Value.EnableAreas) if (razorPagesOptions.Value.AllowAreas)
{ {
var areaRootDirectory = razorPagesOptions.Value.AreaRootDirectory; var areaRootDirectory = razorPagesOptions.Value.AreaRootDirectory;
Debug.Assert(!string.IsNullOrEmpty(areaRootDirectory)); Debug.Assert(!string.IsNullOrEmpty(areaRootDirectory));

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{ {
AddPageModels(context); AddPageModels(context);
if (_pagesOptions.EnableAreas) if (_pagesOptions.AllowAreas)
{ {
AddAreaPageModels(context); AddAreaPageModels(context);
} }

View File

@ -2,18 +2,34 @@
// 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;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace Microsoft.AspNetCore.Mvc.RazorPages namespace Microsoft.AspNetCore.Mvc.RazorPages
{ {
/// <summary> /// <summary>
/// Provides configuration for RazorPages. /// Provides configuration for RazorPages.
/// </summary> /// </summary>
public class RazorPagesOptions public class RazorPagesOptions : IEnumerable<ICompatibilitySwitch>
{ {
private readonly CompatibilitySwitch<bool> _allowAreas;
private readonly ICompatibilitySwitch[] _switches;
private string _root = "/Pages"; private string _root = "/Pages";
private string _areasRoot = "/Areas"; private string _areasRoot = "/Areas";
public RazorPagesOptions()
{
_allowAreas = new CompatibilitySwitch<bool>(nameof(AllowAreas));
_switches = new ICompatibilitySwitch[]
{
_allowAreas,
};
}
/// <summary> /// <summary>
/// Gets a collection of <see cref="IPageConvention"/> instances that are applied during /// Gets a collection of <see cref="IPageConvention"/> instances that are applied during
/// route and page model construction. /// route and page model construction.
@ -45,20 +61,43 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <summary> /// <summary>
/// Gets or sets a value that determines if areas are enabled for Razor Pages. /// Gets or sets a value that determines if areas are enabled for Razor Pages.
/// Defaults to <c>true</c>. /// Defaults to <c>false</c>.
/// </summary>
/// <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>/{AreaRootDirectory}/AreaName/{RootDirectory}/</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="AreaRootDirectory"/>
/// <seealso cref="RootDirectory"/> /// <seealso cref="RootDirectory"/>
/// </para> /// </para>
/// </summary> /// <para>
public bool EnableAreas { get; set; } /// This property is associated with a compatibility switch and can provide a different behavior depending on
/// the configured compatibility version for the application. See <see cref="CompatibilityVersion"/> for
/// guidance and examples of setting the application's compatibility version.
/// </para>
/// <para>
/// Configuring the desired of the value compatibility switch by calling this property's setter will take precedence
/// over the value implied by the application's <see cref="CompatibilityVersion"/>.
/// </para>
/// <para>
/// If the application's compatibility version is set to <see cref="CompatibilityVersion.Version_2_0"/> then
/// this setting will have value <c>false</c> if not explicitly configured.
/// </para>
/// <para>
/// If the application's compatibility version is set to <see cref="CompatibilityVersion.Version_2_1"/> or
/// higher then this setting will have value <c>true</c> if not explicitly configured.
/// </para>
/// </remarks>
public bool AllowAreas
{
get => _allowAreas.Value;
set => _allowAreas.Value = value;
}
/// <summary> /// <summary>
/// Application relative path used as the root of discovery for Razor Page files associated with areas. /// 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. /// Defaults to the <c>/Areas</c> directory under application root.
/// <seealso cref="EnableAreas" /> /// <seealso cref="AllowAreas" />
/// </summary> /// </summary>
public string AreaRootDirectory public string AreaRootDirectory
{ {
@ -78,5 +117,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
_areasRoot = value; _areasRoot = value;
} }
} }
IEnumerator<ICompatibilitySwitch> IEnumerable<ICompatibilitySwitch>.GetEnumerator()
{
return ((IEnumerable<ICompatibilitySwitch>)_switches).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => _switches.GetEnumerator();
} }
} }

View File

@ -0,0 +1,35 @@
// 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.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Mvc.RazorPages
{
internal class RazorPagesOptionsConfigureCompatibilityOptions : ConfigureCompatibilityOptions<RazorPagesOptions>
{
public RazorPagesOptionsConfigureCompatibilityOptions(
ILoggerFactory loggerFactory,
IOptions<MvcCompatibilityOptions> compatibilityOptions)
: base(loggerFactory, compatibilityOptions)
{
}
protected override IReadOnlyDictionary<string, object> DefaultValues
{
get
{
var values = new Dictionary<string, object>();
if (Version >= CompatibilityVersion.Version_2_1)
{
values[nameof(RazorPagesOptions.AllowAreas)] = true;
}
return values;
}
}
}
}

View File

@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
}; };
var options = new RazorPagesOptions var options = new RazorPagesOptions
{ {
EnableAreas = true, AllowAreas = true,
AreaRootDirectory = "/Features", AreaRootDirectory = "/Features",
RootDirectory = "/Files", RootDirectory = "/Files",
}; };
@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
GetDescriptor("/Pages/About.cshtml"), GetDescriptor("/Pages/About.cshtml"),
GetDescriptor("/Areas/Accounts/Pages/Home.cshtml"), GetDescriptor("/Areas/Accounts/Pages/Home.cshtml"),
}; };
var options = new RazorPagesOptions { EnableAreas = false }; var options = new RazorPagesOptions { AllowAreas = false };
var provider = new TestCompiledPageRouteModelProvider(descriptors, options); var provider = new TestCompiledPageRouteModelProvider(descriptors, options);
var context = new PageRouteModelProviderContext(); var context = new PageRouteModelProviderContext();

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
var templateEngine = new RazorTemplateEngine( var templateEngine = new RazorTemplateEngine(
RazorEngine.Create(), RazorEngine.Create(),
new FileProviderRazorProject(accessor)); new FileProviderRazorProject(accessor));
var options = Options.Create(new RazorPagesOptions { EnableAreas = true }); var options = Options.Create(new RazorPagesOptions { AllowAreas = true });
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
// Act // Act
@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
new FileProviderRazorProject(accessor)); new FileProviderRazorProject(accessor));
var options = Options.Create(new RazorPagesOptions var options = Options.Create(new RazorPagesOptions
{ {
EnableAreas = true, AllowAreas = true,
AreaRootDirectory = rootDirectory, AreaRootDirectory = rootDirectory,
}); });
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
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.AreaRootDirectory = "/dir3/dir4";
options.Value.EnableAreas = true; options.Value.AllowAreas = true;
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
@ -175,7 +175,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
RazorEngine.Create(), RazorEngine.Create(),
new FileProviderRazorProject(accessor)); new FileProviderRazorProject(accessor));
templateEngine.Options.ImportsFileName = "_ViewImports.cshtml"; templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
var options = Options.Create(new RazorPagesOptions { EnableAreas = false }); var options = Options.Create(new RazorPagesOptions { AllowAreas = false });
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);

View File

@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
var project = new TestRazorProject(fileProvider); var project = new TestRazorProject(fileProvider);
var optionsManager = Options.Create(new RazorPagesOptions { EnableAreas = true }); var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = true });
var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance);
var context = new PageRouteModelProviderContext(); var context = new PageRouteModelProviderContext();
@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
var project = new TestRazorProject(fileProvider); var project = new TestRazorProject(fileProvider);
var optionsManager = Options.Create(new RazorPagesOptions { EnableAreas = false }); var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = false });
var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance);
var context = new PageRouteModelProviderContext(); var context = new PageRouteModelProviderContext();

View File

@ -23,6 +23,7 @@ using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Razor.Compilation; using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.Internal; using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers; using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
using Microsoft.AspNetCore.Mvc.RazorPages.Internal; using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.TagHelpers;
@ -371,6 +372,20 @@ namespace Microsoft.AspNetCore.Mvc
typeof(RazorPagesRazorViewEngineOptionsSetup), typeof(RazorPagesRazorViewEngineOptionsSetup),
} }
}, },
{
typeof(IPostConfigureOptions<MvcOptions>),
new[]
{
typeof(MvcOptions).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.MvcOptionsConfigureCompatibilityOptions", throwOnError: true),
}
},
{
typeof(IPostConfigureOptions<RazorPagesOptions>),
new[]
{
typeof(RazorPagesOptions).Assembly.GetType("Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptionsConfigureCompatibilityOptions", throwOnError: true),
}
},
{ {
typeof(IActionConstraintProvider), typeof(IActionConstraintProvider),
new Type[] new Type[]

View File

@ -17,7 +17,7 @@ namespace RazorPagesWebSite
.AddCookieTempDataProvider() .AddCookieTempDataProvider()
.AddRazorPagesOptions(options => .AddRazorPagesOptions(options =>
{ {
options.EnableAreas = true; options.AllowAreas = true;
options.Conventions.AuthorizePage("/Conventions/Auth"); options.Conventions.AuthorizePage("/Conventions/Auth");
options.Conventions.AuthorizeFolder("/Conventions/AuthFolder"); options.Conventions.AuthorizeFolder("/Conventions/AuthFolder");
}); });