From 90b093baac9caa52552e7a09156a0f5c4b9add3b Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Thu, 2 Aug 2018 16:59:57 -0700 Subject: [PATCH 1/4] Updated dependencies.props --- build/dependencies.props | 146 +++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9ab9fc484e..6697d0589f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -7,7 +7,7 @@ is not otherwise referenced. They avoid unnecessary changes to the Universe build graph or to product dependencies. Do not use these properties elsewhere. --> - + 0.9.9 0.10.13 2.1.1 @@ -16,87 +16,87 @@ 0.43.0 2.1.1.1 2.1.1 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 2.2.0-preview1-17102 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-a-preview1-routing-api-review-p1-16821 - 2.2.0-a-preview1-routing-api-review-p1-16821 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 5.2.6 2.8.0 2.8.0 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 1.7.0 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 2.1.0 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 2.0.9 2.1.2 2.2.0-preview1-26618-02 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 + 2.2.0-preview1-34869 + 2.2.0-preview1-34869 15.6.1 4.7.49 2.0.3 From ac410b76d9e1a3a454bf21b79491ee6d9d0e15b6 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 3 Aug 2018 16:30:57 +1200 Subject: [PATCH 2/4] Change MvcEndpointInfo to internal (#8210) --- .../MvcApplicationBuilderExtensions.cs | 32 -- .../Builder/MvcEndpointInfo.cs | 2 +- .../Builder/MvcEndpointInfoBuilder.cs | 19 -- .../MvcEndpointInfoBuilderExtensions.cs | 229 -------------- .../Internal/MvcEndpointDataSource.cs | 1 - .../MvcApplicationBuilderExtensionsTest.cs | 20 -- .../MvcEndpointInfoBuilderExtensionsTest.cs | 282 ------------------ 7 files changed, 1 insertion(+), 584 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilder.cs delete mode 100644 src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilderExtensions.cs delete mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcEndpointInfoBuilderExtensionsTest.cs diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcApplicationBuilderExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcApplicationBuilderExtensions.cs index ab4b465492..08baf62c2e 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcApplicationBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcApplicationBuilderExtensions.cs @@ -171,38 +171,6 @@ namespace Microsoft.AspNetCore.Builder } } - public static IApplicationBuilder UseMvcWithEndpoint( - this IApplicationBuilder app, - Action configureRoutes) - { - if (app == null) - { - throw new ArgumentNullException(nameof(app)); - } - - if (configureRoutes == null) - { - throw new ArgumentNullException(nameof(configureRoutes)); - } - - VerifyMvcIsRegistered(app); - - var mvcEndpointDataSource = app.ApplicationServices - .GetRequiredService>() - .OfType() - .First(); - - var constraintResolver = app.ApplicationServices.GetRequiredService(); - - MvcEndpointInfoBuilder routeBuilder = new MvcEndpointInfoBuilder(constraintResolver); - - configureRoutes(routeBuilder); - - mvcEndpointDataSource.ConventionalEndpointInfos.AddRange(routeBuilder.EndpointInfos); - - return app.UseEndpoint(); - } - private static void VerifyMvcIsRegistered(IApplicationBuilder app) { // Verify if AddMvc was done before calling UseMvc diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfo.cs b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfo.cs index ba59c34b44..e0943b82c0 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfo.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfo.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Routing.Template; namespace Microsoft.AspNetCore.Builder { - public class MvcEndpointInfo + internal class MvcEndpointInfo { public MvcEndpointInfo( string name, diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilder.cs b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilder.cs deleted file mode 100644 index 99000fdd08..0000000000 --- a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilder.cs +++ /dev/null @@ -1,19 +0,0 @@ -// 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.Routing; - -namespace Microsoft.AspNetCore.Builder -{ - public class MvcEndpointInfoBuilder - { - public MvcEndpointInfoBuilder(IInlineConstraintResolver constraintResolver) - { - ConstraintResolver = constraintResolver; - } - - public List EndpointInfos { get; } = new List(); - public IInlineConstraintResolver ConstraintResolver { get; } - } -} diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilderExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilderExtensions.cs deleted file mode 100644 index b52ef3692b..0000000000 --- a/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcEndpointInfoBuilderExtensions.cs +++ /dev/null @@ -1,229 +0,0 @@ -// 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.Core; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Routing.Constraints; - -namespace Microsoft.AspNetCore.Builder -{ - /// - /// Provides extension methods for to add endpoints. - /// - public static class MvcEndpointInfoBuilderExtensions - { - #region MapEndpoint - /// - /// Adds a endpoint to the with the specified name and template. - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The URL pattern of the endpoint. - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapEndpoint(this MvcEndpointInfoBuilder endpointBuilder, string name, string template) - { - endpointBuilder.MapEndpoint(name, template, null); - return endpointBuilder; - } - - /// - /// Adds a endpoint to the with the specified name, template, and default values. - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the names - /// and values of the default values. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapEndpoint(this MvcEndpointInfoBuilder endpointBuilder, string name, string template, object defaults) - { - return endpointBuilder.MapEndpoint(name, template, defaults, null); - } - - /// - /// Adds a endpoint to the with the specified name, template, default values, and - /// constraints. - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the names - /// and values of the default values. - /// - /// - /// An object that contains constraints for the endpoint. The object's properties represent the names and values - /// of the constraints. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapEndpoint(this MvcEndpointInfoBuilder endpointBuilder, string name, string template, object defaults, object constraints) - { - return endpointBuilder.MapEndpoint(name, template, defaults, constraints, null); - } - - /// - /// Adds a endpoint to the with the specified name, template, default values, and - /// data tokens. - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the names - /// and values of the default values. - /// - /// - /// An object that contains constraints for the endpoint. The object's properties represent the names and values - /// of the constraints. - /// - /// - /// An object that contains data tokens for the endpoint. The object's properties represent the names and values - /// of the data tokens. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapEndpoint(this MvcEndpointInfoBuilder endpointBuilder, string name, string template, object defaults, object constraints, object dataTokens) - { - endpointBuilder.EndpointInfos.Add(new MvcEndpointInfo( - name, - template, - new RouteValueDictionary(defaults), - new RouteValueDictionary(constraints), - new RouteValueDictionary(dataTokens), - endpointBuilder.ConstraintResolver)); - - return endpointBuilder; - } - #endregion - - #region MapAreaEndpoint - /// - /// Adds a endpoint to the with the given MVC area with the specified - /// , and . - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The MVC area name. - /// The URL pattern of the endpoint. - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapAreaEndpoint( - this MvcEndpointInfoBuilder endpointBuilder, - string name, - string areaName, - string template) - { - MapAreaEndpoint(endpointBuilder, name, areaName, template, defaults: null, constraints: null, dataTokens: null); - return endpointBuilder; - } - - /// - /// Adds a endpoint to the with the given MVC area with the specified - /// , , , and - /// . - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The MVC area name. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the - /// names and values of the default values. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapAreaEndpoint( - this MvcEndpointInfoBuilder endpointBuilder, - string name, - string areaName, - string template, - object defaults) - { - MapAreaEndpoint(endpointBuilder, name, areaName, template, defaults, constraints: null, dataTokens: null); - return endpointBuilder; - } - - /// - /// Adds a endpoint to the with the given MVC area with the specified - /// , , , - /// , and . - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The MVC area name. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the - /// names and values of the default values. - /// - /// - /// An object that contains constraints for the endpoint. The object's properties represent the names and - /// values of the constraints. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapAreaEndpoint( - this MvcEndpointInfoBuilder endpointBuilder, - string name, - string areaName, - string template, - object defaults, - object constraints) - { - MapAreaEndpoint(endpointBuilder, name, areaName, template, defaults, constraints, dataTokens: null); - return endpointBuilder; - } - - /// - /// Adds a endpoint to the with the given MVC area with the specified - /// , , , - /// , , and . - /// - /// The to add the endpoint to. - /// The name of the endpoint. - /// The MVC area name. - /// The URL pattern of the endpoint. - /// - /// An object that contains default values for endpoint parameters. The object's properties represent the - /// names and values of the default values. - /// - /// - /// An object that contains constraints for the endpoint. The object's properties represent the names and - /// values of the constraints. - /// - /// - /// An object that contains data tokens for the endpoint. The object's properties represent the names and - /// values of the data tokens. - /// - /// A reference to this instance after the operation has completed. - public static MvcEndpointInfoBuilder MapAreaEndpoint( - this MvcEndpointInfoBuilder endpointBuilder, - string name, - string areaName, - string template, - object defaults, - object constraints, - object dataTokens) - { - if (endpointBuilder == null) - { - throw new ArgumentNullException(nameof(endpointBuilder)); - } - - if (string.IsNullOrEmpty(areaName)) - { - throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(areaName)); - } - - var defaultsDictionary = new RouteValueDictionary(defaults); - defaultsDictionary["area"] = defaultsDictionary["area"] ?? areaName; - - var constraintsDictionary = new RouteValueDictionary(constraints); - constraintsDictionary["area"] = constraintsDictionary["area"] ?? new StringRouteConstraint(areaName); - - endpointBuilder.MapEndpoint(name, template, defaultsDictionary, constraintsDictionary, dataTokens); - return endpointBuilder; - } - #endregion - } -} diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs index 180b34011f..3770856e64 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs @@ -442,7 +442,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal } } - // REVIEW: Infos added after endpoints are initialized will not be used public List ConventionalEndpointInfos { get; } private class RouteNameMetadata : IRouteNameMetadata diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcApplicationBuilderExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcApplicationBuilderExtensionsTest.cs index 39fd3847db..d731a697f2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcApplicationBuilderExtensionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcApplicationBuilderExtensionsTest.cs @@ -37,26 +37,6 @@ namespace Microsoft.AspNetCore.Mvc.Core.Builder exception.Message); } - [Fact] - public void UseMvcWithEndpoint_ThrowsInvalidOperationException_IfMvcMarkerServiceIsNotRegistered() - { - // Arrange - var applicationBuilderMock = new Mock(); - applicationBuilderMock - .Setup(s => s.ApplicationServices) - .Returns(Mock.Of()); - - // Act & Assert - var exception = Assert.Throws( - () => applicationBuilderMock.Object.UseMvcWithEndpoint(rb => { })); - - Assert.Equal( - "Unable to find the required services. Please add all the required services by calling " + - "'IServiceCollection.AddMvc' inside the call to 'ConfigureServices(...)' " + - "in the application startup code.", - exception.Message); - } - [Fact] public void UseMvc_EndpointRoutingDisabled_NoEndpointInfos() { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcEndpointInfoBuilderExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcEndpointInfoBuilderExtensionsTest.cs deleted file mode 100644 index 4a1431793b..0000000000 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Builder/MvcEndpointInfoBuilderExtensionsTest.cs +++ /dev/null @@ -1,282 +0,0 @@ -// 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 System.Linq; -using System.Text; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Routing.Constraints; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.Mvc.Core.Test.Builder -{ - public class MvcEndpointInfoBuilderExtensionsTest - { - #region MapAreaEndpoint - [Fact] - public void MapAreaEndpoint_Simple() - { - // Arrange - var builder = CreateEndpointBuilder(); - - // Act - builder.MapAreaEndpoint(name: null, areaName: "admin", template: "site/Admin/"); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Null(endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - }); - Assert.Empty(endpointInfo.DataTokens); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal("admin", kvp.Value); - }); - } - - [Fact] - public void MapAreaEndpoint_Defaults() - { - // Arrange - var builder = CreateEndpointBuilder(); - - // Act - builder.MapAreaEndpoint( - name: "admin_area", - areaName: "admin", - template: "site/Admin/", - defaults: new { action = "Home" }); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Equal("admin_area", endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - }); - Assert.Empty(endpointInfo.DataTokens); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("action", kvp.Key); - Assert.Equal("Home", kvp.Value); - }, - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal("admin", kvp.Value); - }); - } - - [Fact] - public void MapAreaEndpoint_DefaultsAndConstraints() - { - // Arrange - var builder = CreateEndpointBuilder(); - - // Act - builder.MapAreaEndpoint( - name: "admin_area", - areaName: "admin", - template: "site/Admin/", - defaults: new { action = "Home" }, - constraints: new { id = new IntRouteConstraint() }); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Equal("admin_area", endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - }, - kvp => - { - Assert.Equal("id", kvp.Key); - Assert.IsType(kvp.Value); - }); - Assert.Empty(endpointInfo.DataTokens); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("action", kvp.Key); - Assert.Equal("Home", kvp.Value); - }, - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal("admin", kvp.Value); - }); - } - - [Fact] - public void MapAreaEndpoint_DefaultsConstraintsAndDataTokens() - { - // Arrange - var builder = CreateEndpointBuilder(); - - // Act - builder.MapAreaEndpoint( - name: "admin_area", - areaName: "admin", - template: "site/Admin/", - defaults: new { action = "Home" }, - constraints: new { id = new IntRouteConstraint() }, - dataTokens: new { some_token = "hello" }); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Equal("admin_area", endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - }, - kvp => - { - Assert.Equal("id", kvp.Key); - Assert.IsType(kvp.Value); - }); - Assert.Collection( - endpointInfo.DataTokens.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("some_token", kvp.Key); - Assert.Equal("hello", kvp.Value); - }); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("action", kvp.Key); - Assert.Equal("Home", kvp.Value); - }, - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal("admin", kvp.Value); - }); - } - - [Fact] - public void MapAreaEndpoint_DoesNotReplaceValuesForAreaIfAlreadyPresentInConstraintsOrDefaults() - { - // Arrange - var builder = CreateEndpointBuilder(); - - // Act - builder.MapAreaEndpoint( - name: "admin_area", - areaName: "admin", - template: "site/Admin/", - defaults: new { area = "Home" }, - constraints: new { area = new IntRouteConstraint() }, - dataTokens: new { some_token = "hello" }); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Equal("admin_area", endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - }); - Assert.Collection( - endpointInfo.DataTokens.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("some_token", kvp.Key); - Assert.Equal("hello", kvp.Value); - }); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal("Home", kvp.Value); - }); - } - - [Fact] - public void MapAreaEndpoint_UsesPassedInAreaNameAsIs() - { - // Arrange - var builder = CreateEndpointBuilder(); - var areaName = "user.admin"; - - // Act - builder.MapAreaEndpoint(name: null, areaName: areaName, template: "site/Admin/"); - - // Assert - var endpointInfo = Assert.Single(builder.EndpointInfos); - - Assert.Null(endpointInfo.Name); - Assert.Equal("site/Admin/", endpointInfo.Template); - Assert.Collection( - endpointInfo.Constraints.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.IsType(kvp.Value); - - var values = new RouteValueDictionary(new { area = areaName }); - var match = kvp.Value.Match( - new DefaultHttpContext(), - route: new Mock().Object, - routeKey: kvp.Key, - values: values, - routeDirection: RouteDirection.UrlGeneration); - - Assert.True(match); - }); - Assert.Empty(endpointInfo.DataTokens); - Assert.Collection( - endpointInfo.Defaults.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("area", kvp.Key); - Assert.Equal(kvp.Value, areaName); - }); - } - #endregion - - private MvcEndpointInfoBuilder CreateEndpointBuilder() - { - var builder = new MvcEndpointInfoBuilder(Mock.Of()); - return builder; - } - } -} \ No newline at end of file From a375cba3590074c5182b50a71ad21b61a4b882df Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 3 Aug 2018 12:04:44 -0700 Subject: [PATCH 3/4] Copy action constraints and EndPointMetadata when setting up a PageActionDescriptor (#8208) * Copy action constraints and EndPointMetadata when setting up a PageActionDescriptor Fixes #8207 --- .../PageActionDescriptorProvider.cs | 4 +- .../CompiledPageActionDescriptorBuilder.cs | 1 + .../PageActionDescriptorProviderTest.cs | 69 +++++++++++++++++++ ...CompiledPageActionDescriptorBuilderTest.cs | 2 + 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs index 7e1dbb47c2..06bc6f52eb 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs @@ -75,6 +75,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure { var descriptor = new PageActionDescriptor { + ActionConstraints = selector.ActionConstraints.ToList(), + AreaName = model.AreaName, AttributeRouteInfo = new AttributeRouteInfo { Name = selector.AttributeRouteModel.Name, @@ -84,11 +86,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure SuppressPathMatching = selector.AttributeRouteModel.SuppressPathMatching, }, DisplayName = $"Page: {model.ViewEnginePath}", + EndpointMetadata = selector.EndpointMetadata.ToList(), FilterDescriptors = Array.Empty(), Properties = new Dictionary(model.Properties), RelativePath = model.RelativePath, ViewEnginePath = model.ViewEnginePath, - AreaName = model.AreaName, }; foreach (var kvp in model.RouteValues) diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/CompiledPageActionDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/CompiledPageActionDescriptorBuilder.cs index 29f7214448..41055bf878 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/CompiledPageActionDescriptorBuilder.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/CompiledPageActionDescriptorBuilder.cs @@ -49,6 +49,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal ActionConstraints = actionDescriptor.ActionConstraints, AttributeRouteInfo = actionDescriptor.AttributeRouteInfo, BoundProperties = boundProperties, + EndpointMetadata = actionDescriptor.EndpointMetadata, FilterDescriptors = filters, HandlerMethods = handlerMethods, HandlerTypeInfo = applicationModel.HandlerType, diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs index 095a5f5415..4b1e2c4429 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Options; using Moq; @@ -167,6 +168,74 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure Assert.Equal("Accounts/Test/{id:int?}", descriptor.AttributeRouteInfo.Template); } + [Fact] + public void GetDescriptors_CopiesActionConstraintsFromModel() + { + // Arrange + var expected = Mock.Of(); + var model = new PageRouteModel("/Areas/Accounts/Pages/Test.cshtml", "/Test", "Accounts") + { + Selectors = + { + new SelectorModel + { + AttributeRouteModel = new AttributeRouteModel(), + ActionConstraints = { expected } + } + }, + }; + var applicationModelProvider = new TestPageRouteModelProvider(model); + var provider = new PageActionDescriptorProvider( + new[] { applicationModelProvider }, + GetAccessor(), + GetRazorPagesOptions()); + var context = new ActionDescriptorProviderContext(); + + // Act + provider.OnProvidersExecuting(context); + + // Assert + var result = Assert.Single(context.Results); + var descriptor = Assert.IsType(result); + Assert.Equal(model.RelativePath, descriptor.RelativePath); + var actual = Assert.Single(descriptor.ActionConstraints); + Assert.Same(expected, actual); + } + + [Fact] + public void GetDescriptors_CopiesEndPointMetadataFromModel() + { + // Arrange + var expected = new object(); + var model = new PageRouteModel("/Test.cshtml", "/Test", "Accounts") + { + Selectors = + { + new SelectorModel + { + AttributeRouteModel = new AttributeRouteModel(), + EndpointMetadata = { expected } + } + }, + }; + var applicationModelProvider = new TestPageRouteModelProvider(model); + var provider = new PageActionDescriptorProvider( + new[] { applicationModelProvider }, + GetAccessor(), + GetRazorPagesOptions()); + var context = new ActionDescriptorProviderContext(); + + // Act + provider.OnProvidersExecuting(context); + + // Assert + var result = Assert.Single(context.Results); + var descriptor = Assert.IsType(result); + Assert.Equal(model.RelativePath, descriptor.RelativePath); + var actual = Assert.Single(descriptor.EndpointMetadata); + Assert.Same(expected, actual); + } + [Fact] public void GetDescriptors_AddsActionDescriptorForEachSelector() { diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageActionDescriptorBuilderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageActionDescriptorBuilderTest.cs index 2d08aee3d8..7d12648d04 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageActionDescriptorBuilderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageActionDescriptorBuilderTest.cs @@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { ActionConstraints = new List(), AttributeRouteInfo = new AttributeRouteInfo(), + EndpointMetadata = new List(), FilterDescriptors = new List(), RelativePath = "/Foo", RouteValues = new Dictionary(), @@ -40,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal // Assert Assert.Same(actionDescriptor.ActionConstraints, actual.ActionConstraints); Assert.Same(actionDescriptor.AttributeRouteInfo, actual.AttributeRouteInfo); + Assert.Same(actionDescriptor.EndpointMetadata, actual.EndpointMetadata); Assert.Same(actionDescriptor.RelativePath, actual.RelativePath); Assert.Same(actionDescriptor.RouteValues, actual.RouteValues); Assert.Same(actionDescriptor.ViewEnginePath, actual.ViewEnginePath); From 6efb51d8179ae6981300aaadd83fb5c8e45e6eb0 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 3 Aug 2018 14:46:45 -0700 Subject: [PATCH 4/4] Add Microsoft.AspNetCore.Mvc.Api.Analyzers to Mvc.sln --- Mvc.sln | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mvc.sln b/Mvc.sln index 8223801973..7478c7b22e 100644 --- a/Mvc.sln +++ b/Mvc.sln @@ -178,6 +178,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicViews", "benchmarkapps EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mvc.Api.Analyzers.Test", "test\Mvc.Api.Analyzers.Test\Mvc.Api.Analyzers.Test.csproj", "{DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Mvc.Api.Analyzers", "src\Microsoft.AspNetCore.Mvc.Api.Analyzers\Microsoft.AspNetCore.Mvc.Api.Analyzers.csproj", "{3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -938,6 +940,18 @@ Global {DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|Mixed Platforms.Build.0 = Release|Any CPU {DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|x86.ActiveCfg = Release|Any CPU {DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87}.Release|x86.Build.0 = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|x86.ActiveCfg = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Debug|x86.Build.0 = Debug|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|Any CPU.Build.0 = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|x86.ActiveCfg = Release|Any CPU + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1010,6 +1024,7 @@ Global {910F023A-88E3-4CB4-8793-AC4005C7B421} = {2859F266-673A-45A2-9E3C-7B39C6DDD38E} {E89EB74D-C1CE-456F-B42D-CCF1575E0CFB} = {2859F266-673A-45A2-9E3C-7B39C6DDD38E} {DD7B9F20-354C-4D9E-8C8A-8AE6E7595A87} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1} + {3B550487-10E4-4E6D-9CEF-B1B4CA1253DA} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A}