Add convenience extension methods for IPageApplicationModelConvention
This commit is contained in:
parent
f6d25f7117
commit
7cadb58e12
|
|
@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
|
|||
/// <summary>
|
||||
/// Allows customization of the of the <see cref="PageApplicationModel"/>.
|
||||
/// </summary>
|
||||
public interface IPageModelConvention
|
||||
public interface IPageApplicationModelConvention
|
||||
{
|
||||
/// <summary>
|
||||
/// Called to apply the convention to the <see cref="PageApplicationModel"/>.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions methods for configuring Razor Pages via an <see cref="IMvcBuilder"/>.
|
||||
/// </summary>
|
||||
public static class MvcRazorPagesMvcBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Configures a set of <see cref="RazorViewEngineOptions"/> for the application.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
|
||||
/// <param name="setupAction">An action to configure the <see cref="RazorViewEngineOptions"/>.</param>
|
||||
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
|
||||
public static IMvcBuilder AddRazorPagesOptions(
|
||||
this IMvcBuilder builder,
|
||||
Action<RazorPagesOptions> setupAction)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (setupAction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(setupAction));
|
||||
}
|
||||
|
||||
builder.Services.Configure(setupAction);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
|||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
@ -51,6 +52,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
// Internal for testing.
|
||||
internal static void AddServices(IServiceCollection services)
|
||||
{
|
||||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Transient<
|
||||
IConfigureOptions<RazorPagesOptions>,
|
||||
RazorPagesOptionsSetup>());
|
||||
|
||||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Singleton<IActionDescriptorProvider, PageActionDescriptorProvider>());
|
||||
|
||||
|
|
@ -72,6 +78,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddSingleton<IActionDescriptorChangeProvider, PageActionDescriptorChangeProvider>();
|
||||
|
||||
services.TryAddSingleton<TempDataPropertyProvider>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions for <see cref="RazorPagesOptions"/>.
|
||||
/// </summary>
|
||||
public static class RazorPagesOptionsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Configures the specified <paramref name="filter"/> to apply to all Razor Pages.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RazorPagesOptions"/> to configure.</param>
|
||||
/// <param name="filter">The <see cref="IFilterMetadata"/> to add.</param>
|
||||
/// <returns>The <see cref="RazorPagesOptions"/>.</returns>
|
||||
public static RazorPagesOptions ConfigureFilter(this RazorPagesOptions options, IFilterMetadata filter)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (filter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(filter));
|
||||
}
|
||||
|
||||
options.Conventions.Add(new FolderConvention("/", model => model.Filters.Add(filter)));
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="AuthorizeFilter"/> with the specified policy to the page with the specified path.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RazorPagesOptions"/> to configure.</param>
|
||||
/// <param name="path">The path of the Razor Page.</param>
|
||||
/// <param name="policy">The authorization policy.</param>
|
||||
/// <returns>The <see cref="RazorPagesOptions"/>.</returns>
|
||||
public static RazorPagesOptions AuthorizePage(this RazorPagesOptions options, string path, string policy)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path));
|
||||
}
|
||||
|
||||
var authorizeFilter = new AuthorizeFilter(policy);
|
||||
options.Conventions.Add(new PageConvention(path, model => model.Filters.Add(authorizeFilter)));
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="AuthorizeFilter"/> with the specified policy to all page under the specified path.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="RazorPagesOptions"/> to configure.</param>
|
||||
/// <param name="folderPath">The folder path.</param>
|
||||
/// <param name="policy">The authorization policy.</param>
|
||||
/// <returns>The <see cref="RazorPagesOptions"/>.</returns>
|
||||
public static RazorPagesOptions AuthorizeFolder(this RazorPagesOptions options, string folderPath, string policy)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(folderPath))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(folderPath));
|
||||
}
|
||||
|
||||
var authorizeFilter = new AuthorizeFilter(policy);
|
||||
options.Conventions.Add(new FolderConvention(folderPath, model => model.Filters.Add(authorizeFilter)));
|
||||
return options;
|
||||
}
|
||||
|
||||
private class PageConvention : IPageApplicationModelConvention
|
||||
{
|
||||
private readonly string _path;
|
||||
private readonly Action<PageApplicationModel> _action;
|
||||
|
||||
public PageConvention(string path, Action<PageApplicationModel> action)
|
||||
{
|
||||
_path = path;
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Apply(PageApplicationModel model)
|
||||
{
|
||||
if (string.Equals(model.ViewEnginePath, _path, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_action(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FolderConvention : IPageApplicationModelConvention
|
||||
{
|
||||
private readonly string _folderPath;
|
||||
private readonly Action<PageApplicationModel> _action;
|
||||
|
||||
public FolderConvention(string folderPath, Action<PageApplicationModel> action)
|
||||
{
|
||||
_folderPath = folderPath.TrimEnd('/');
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Apply(PageApplicationModel model)
|
||||
{
|
||||
var viewEnginePath = model.ViewEnginePath;
|
||||
|
||||
var applyConvention = _folderPath == "/" ||
|
||||
(viewEnginePath.Length > _folderPath.Length &&
|
||||
viewEnginePath.StartsWith(_folderPath, StringComparison.OrdinalIgnoreCase) &&
|
||||
viewEnginePath[_folderPath.Length] == '/');
|
||||
|
||||
if (applyConvention)
|
||||
{
|
||||
_action(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
|||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
|
@ -85,9 +84,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
model.Selectors.Add(CreateSelectorModel(parentDirectoryPath, template));
|
||||
}
|
||||
|
||||
model.Filters.Add(new SaveTempDataPropertyFilter()); // Support for [TempData] on properties
|
||||
model.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); // Always require an antiforgery token on post
|
||||
|
||||
for (var i = 0; i < _pagesOptions.Conventions.Count; i++)
|
||||
{
|
||||
_pagesOptions.Conventions[i].Apply(model);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
{
|
||||
public class RazorPagesOptionsSetup : IConfigureOptions<RazorPagesOptions>
|
||||
{
|
||||
public void Configure(RazorPagesOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
// Support for [TempData] on properties
|
||||
options.ConfigureFilter(new SaveTempDataPropertyFilter());
|
||||
// Always require an antiforgery token on post
|
||||
options.ConfigureFilter(new AutoValidateAntiforgeryTokenAttribute());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
|
||||
|
|
@ -12,9 +13,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
|||
public class RazorPagesOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="IPageModelConvention"/> instances that will be applied to
|
||||
/// Gets a list of <see cref="IPageApplicationModelConvention"/> instances that will be applied to
|
||||
/// the <see cref="PageModel"/> when discovering Razor Pages.
|
||||
/// </summary>
|
||||
public IList<IPageModelConvention> Conventions { get; } = new List<IPageModelConvention>();
|
||||
public IList<IPageApplicationModelConvention> Conventions { get; } = new List<IPageApplicationModelConvention>();
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +131,20 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("Hi2", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AuthorizePage_AddsAuthorizationForSpecificPages()
|
||||
{
|
||||
// Arrange
|
||||
var url = "/HelloWorldWithAuth";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
Assert.Equal("/Login?ReturnUrl=%2FHelloWorldWithAuth", response.Headers.Location.PathAndQuery);
|
||||
}
|
||||
|
||||
private static string GetCookie(HttpResponseMessage response)
|
||||
{
|
||||
var setCookie = response.Headers.GetValues("Set-Cookie").ToArray();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// 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.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public class MvcRazorPagesMvcBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddRazorPagesOptions_AddsApplicationModelConventions()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection().AddOptions();
|
||||
var expected = Mock.Of<IPageApplicationModelConvention>();
|
||||
var builder = new MvcBuilder(services, new ApplicationPartManager());
|
||||
builder.AddRazorPagesOptions(options =>
|
||||
{
|
||||
options.Conventions.Add(expected);
|
||||
});
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var accessor = serviceProvider.GetRequiredService<IOptions<RazorPagesOptions>>();
|
||||
|
||||
// Act
|
||||
var conventions = accessor.Value.Conventions;
|
||||
|
||||
// Assert
|
||||
Assert.Collection(conventions,
|
||||
convention => Assert.Same(expected, convention));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// 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.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public class RazorPagesOptionsExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddFilter_AddsFiltersToAllPages()
|
||||
{
|
||||
// Arrange
|
||||
var filter = Mock.Of<IFilterMetadata>();
|
||||
var options = new RazorPagesOptions();
|
||||
var models = new[]
|
||||
{
|
||||
new PageApplicationModel("/Pages/Index.cshtml", "/Index.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Account.cshtml", "/Users/Account.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Contact.cshtml", "/Users/Contact.cshtml"),
|
||||
};
|
||||
|
||||
// Act
|
||||
options.ConfigureFilter(filter);
|
||||
ApplyConventions(options, models);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(models,
|
||||
model => Assert.Same(filter, Assert.Single(model.Filters)),
|
||||
model => Assert.Same(filter, Assert.Single(model.Filters)),
|
||||
model => Assert.Same(filter, Assert.Single(model.Filters)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthorizePage_AddsAuthorizeFilterToSpecificPage()
|
||||
{
|
||||
// Arrange
|
||||
var options = new RazorPagesOptions();
|
||||
var models = new[]
|
||||
{
|
||||
new PageApplicationModel("/Pages/Index.cshtml", "/Index.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Account.cshtml", "/Users/Account.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Contact.cshtml", "/Users/Contact.cshtml"),
|
||||
};
|
||||
|
||||
// Act
|
||||
options.AuthorizePage("/Users/Account.cshtml", "Manage-Accounts");
|
||||
ApplyConventions(options, models);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(models,
|
||||
model => Assert.Empty(model.Filters),
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Users/Account.cshtml", model.ViewEnginePath);
|
||||
var authorizeFilter = Assert.IsType<AuthorizeFilter>(Assert.Single(model.Filters));
|
||||
var authorizeData = Assert.IsType<AuthorizeAttribute>(Assert.Single(authorizeFilter.AuthorizeData));
|
||||
Assert.Equal("Manage-Accounts", authorizeData.Policy);
|
||||
},
|
||||
model => Assert.Empty(model.Filters));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/Users")]
|
||||
[InlineData("/Users/")]
|
||||
public void AuthorizePage_AddsAuthorizeFilterToPagesUnderFolder(string folderName)
|
||||
{
|
||||
// Arrange
|
||||
var options = new RazorPagesOptions();
|
||||
var models = new[]
|
||||
{
|
||||
new PageApplicationModel("/Pages/Index.cshtml", "/Index.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Account.cshtml", "/Users/Account.cshtml"),
|
||||
new PageApplicationModel("/Pages/Users/Contact.cshtml", "/Users/Contact.cshtml"),
|
||||
};
|
||||
|
||||
// Act
|
||||
options.AuthorizeFolder(folderName, "Manage-Accounts");
|
||||
ApplyConventions(options, models);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(models,
|
||||
model => Assert.Empty(model.Filters),
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Users/Account.cshtml", model.ViewEnginePath);
|
||||
var authorizeFilter = Assert.IsType<AuthorizeFilter>(Assert.Single(model.Filters));
|
||||
var authorizeData = Assert.IsType<AuthorizeAttribute>(Assert.Single(authorizeFilter.AuthorizeData));
|
||||
Assert.Equal("Manage-Accounts", authorizeData.Policy);
|
||||
},
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Users/Contact.cshtml", model.ViewEnginePath);
|
||||
var authorizeFilter = Assert.IsType<AuthorizeFilter>(Assert.Single(model.Filters));
|
||||
var authorizeData = Assert.IsType<AuthorizeAttribute>(Assert.Single(authorizeFilter.AuthorizeData));
|
||||
Assert.Equal("Manage-Accounts", authorizeData.Policy);
|
||||
});
|
||||
}
|
||||
|
||||
private static void ApplyConventions(RazorPagesOptions options, PageApplicationModel[] models)
|
||||
{
|
||||
foreach (var convention in options.Conventions)
|
||||
{
|
||||
foreach (var model in models)
|
||||
{
|
||||
convention.Apply(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
|||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -30,7 +31,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -53,7 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -80,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -109,7 +110,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act and Assert
|
||||
|
|
@ -133,7 +134,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -170,7 +171,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor<MvcOptions>(),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -208,7 +209,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor(options),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -250,7 +251,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor(options),
|
||||
GetAccessor<RazorPagesOptions>());
|
||||
GetRazorPagesOptions());
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -291,14 +292,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var localFilter = Mock.Of<IFilterMetadata>();
|
||||
var options = new MvcOptions();
|
||||
options.Filters.Add(globalFilter);
|
||||
var convention = new Mock<IPageModelConvention>();
|
||||
var convention = new Mock<IPageApplicationModelConvention>();
|
||||
convention.Setup(c => c.Apply(It.IsAny<PageApplicationModel>()))
|
||||
.Callback((PageApplicationModel model) =>
|
||||
{
|
||||
model.Filters.Add(localFilter);
|
||||
});
|
||||
var razorOptions = new RazorPagesOptions();
|
||||
razorOptions.Conventions.Add(convention.Object);
|
||||
var razorOptions = GetRazorPagesOptions();
|
||||
razorOptions.Value.Conventions.Add(convention.Object);
|
||||
|
||||
var razorProject = new Mock<RazorProject>();
|
||||
razorProject.Setup(p => p.EnumerateItems("/"))
|
||||
|
|
@ -309,7 +310,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
var provider = new PageActionDescriptorProvider(
|
||||
razorProject.Object,
|
||||
GetAccessor(options),
|
||||
GetAccessor(razorOptions));
|
||||
razorOptions);
|
||||
var context = new ActionDescriptorProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -349,6 +350,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
return accessor.Object;
|
||||
}
|
||||
|
||||
private static IOptions<RazorPagesOptions> GetRazorPagesOptions()
|
||||
{
|
||||
return new OptionsManager<RazorPagesOptions>(new[] { new RazorPagesOptionsSetup() });
|
||||
}
|
||||
|
||||
private static RazorProjectItem GetProjectItem(string basePath, string path, string content)
|
||||
{
|
||||
var testFileInfo = new TestFileInfo
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
// 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.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
{
|
||||
public class RazorPagesOptionsSetupTest
|
||||
{
|
||||
[Fact]
|
||||
public void Configure_AddsGlobalFilters()
|
||||
{
|
||||
// Arrange
|
||||
var options = new RazorPagesOptions();
|
||||
var setup = new RazorPagesOptionsSetup();
|
||||
var applicationModel = new PageApplicationModel("/Home.cshtml", "/Home.cshtml");
|
||||
|
||||
// Act
|
||||
setup.Configure(options);
|
||||
foreach (var convention in options.Conventions)
|
||||
{
|
||||
convention.Apply(applicationModel);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Collection(applicationModel.Filters,
|
||||
filter => Assert.IsType<SaveTempDataPropertyFilter>(filter),
|
||||
filter => Assert.IsType<AutoValidateAntiforgeryTokenAttribute>(filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@page
|
||||
|
||||
Can't see me
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@page
|
||||
@Context.Request.Query["ReturnUrl"]
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Mvc.TestConfiguration\Microsoft.AspNetCore.Mvc.TestConfiguration.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.2.0-*" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.2.0-*" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.2.0-*" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.2.0-*" />
|
||||
|
|
|
|||
|
|
@ -10,15 +10,28 @@ namespace RazorPagesWebSite
|
|||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc().AddCookieTempDataProvider();
|
||||
services
|
||||
.AddMvc()
|
||||
.AddCookieTempDataProvider()
|
||||
.AddRazorPagesOptions(options =>
|
||||
{
|
||||
options.AuthorizePage("/HelloWorldWithAuth", string.Empty);
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseCultureReplacer();
|
||||
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||
{
|
||||
LoginPath = "/Login",
|
||||
AutomaticAuthenticate = true,
|
||||
AutomaticChallenge = true
|
||||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue