From c9887e027a97b07a3ae7699112b9a2620a36e553 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Tue, 20 Nov 2018 11:21:46 -0800 Subject: [PATCH] Simplify parameter transformer usage --- .../ApplicationModels/ActionModel.cs | 13 +++++++++++++ .../ApplicationModels/ApplicationModelFactory.cs | 7 ++----- .../RouteTokenTransformerConvention.cs | 2 +- .../ApplicationModels/PageRouteModel.cs | 13 +++++++++++++ .../PageRouteTransformerConvention.cs | 2 +- .../PageActionDescriptorProvider.cs | 7 ++----- .../ApplicationModels/ActionModelTest.cs | 3 +++ .../RouteTokenTransformerConventionTest.cs | 8 +++----- .../PageRouteTransformerConventionTest.cs | 5 ++--- .../ControllerRouteTokenTransformerConvention.cs | 15 ++++----------- 10 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ActionModel.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ActionModel.cs index 59cc05b4e4..9571152114 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ActionModel.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ActionModel.cs @@ -50,6 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels ActionMethod = other.ActionMethod; ActionName = other.ActionName; + RouteParameterTransformer = other.RouteParameterTransformer; // Not making a deep copy of the controller, this action still belongs to the same controller. Controller = other.Controller; @@ -93,6 +94,18 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels public IList Parameters { get; } + /// + /// Gets or sets an that will be used to transform + /// built-in route parameters such as action, controller, and area as well as + /// additional parameters specified by into static segments in the route template. + /// + /// + /// + /// This feature only applies when using endpoint routing. + /// + /// + public IOutboundParameterTransformer RouteParameterTransformer { get; set; } + /// /// Gets a collection of route values that must be present in the /// for the corresponding action to be selected. diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ApplicationModelFactory.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ApplicationModelFactory.cs index f93fcb5eff..fae18d4481 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ApplicationModelFactory.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ApplicationModelFactory.cs @@ -159,20 +159,17 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels routeValues.TryAdd(kvp.Key, kvp.Value); } - action.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var obj); - var transformer = obj as IOutboundParameterTransformer; - selector.AttributeRouteModel.Template = AttributeRouteModel.ReplaceTokens( selector.AttributeRouteModel.Template, routeValues, - transformer); + action.RouteParameterTransformer); if (selector.AttributeRouteModel.Name != null) { selector.AttributeRouteModel.Name = AttributeRouteModel.ReplaceTokens( selector.AttributeRouteModel.Name, routeValues, - transformer); + action.RouteParameterTransformer); } } catch (InvalidOperationException ex) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/RouteTokenTransformerConvention.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/RouteTokenTransformerConvention.cs index 004e4a22c3..44492420c1 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/RouteTokenTransformerConvention.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/RouteTokenTransformerConvention.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { if (ShouldApply(action)) { - action.Properties[typeof(IOutboundParameterTransformer)] = _parameterTransformer; + action.RouteParameterTransformer = _parameterTransformer; } } diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteModel.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteModel.cs index a150977094..6c543a6b6c 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteModel.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteModel.cs @@ -55,6 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels RelativePath = other.RelativePath; ViewEnginePath = other.ViewEnginePath; AreaName = other.AreaName; + RouteParameterTransformer = other.RouteParameterTransformer; Properties = new Dictionary(other.Properties); Selectors = new List(other.Selectors.Select(m => new SelectorModel(m))); @@ -113,5 +114,17 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels /// /// public IDictionary RouteValues { get; } + + /// + /// Gets or sets an that will be used to transform + /// built-in route parameters such as action, controller, and area as well as + /// additional parameters specified by into static segments in the route template. + /// + /// + /// + /// This feature only applies when using endpoint routing. + /// + /// + public IOutboundParameterTransformer RouteParameterTransformer { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteTransformerConvention.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteTransformerConvention.cs index df47d3b7c2..14903649a9 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteTransformerConvention.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/ApplicationModels/PageRouteTransformerConvention.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { if (ShouldApply(model)) { - model.Properties[typeof(IOutboundParameterTransformer)] = _parameterTransformer; + model.RouteParameterTransformer = _parameterTransformer; } } diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs index 3e47042bdc..23a449e731 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageActionDescriptorProvider.cs @@ -113,11 +113,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure private static string TransformPageRoute(PageRouteModel model, SelectorModel selectorModel) { - model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var transformer); - var pageRouteTransformer = transformer as IOutboundParameterTransformer; - // Transformer not set on page route - if (pageRouteTransformer == null) + if (model.RouteParameterTransformer == null) { return selectorModel.AttributeRouteModel.Template; } @@ -134,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure var segments = pageRouteMetadata.PageRoute.Split('/'); for (var i = 0; i < segments.Length; i++) { - segments[i] = pageRouteTransformer.TransformOutbound(segments[i]); + segments[i] = model.RouteParameterTransformer.TransformOutbound(segments[i]); } var transformedPageRoute = string.Join("/", segments); diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/ActionModelTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/ActionModelTest.cs index 662b6ef787..6e2b6fec71 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/ActionModelTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/ActionModelTest.cs @@ -7,6 +7,8 @@ using System.Reflection; using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.Routing; +using Moq; using Xunit; namespace Microsoft.AspNetCore.Mvc.ApplicationModels @@ -75,6 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels (typeof(TestController).GetTypeInfo(), new List()); action.Filters.Add(new MyFilterAttribute()); + action.RouteParameterTransformer = Mock.Of(); action.RouteValues.Add("key", "value"); action.Properties.Add(new KeyValuePair("test key", "test value")); diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/RouteTokenTransformerConventionTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/RouteTokenTransformerConventionTest.cs index 52214026ef..1aa426bcd2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/RouteTokenTransformerConventionTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationModels/RouteTokenTransformerConventionTest.cs @@ -3,11 +3,10 @@ using System; using System.Reflection; -using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Routing; using Xunit; -namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels +namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public class RouteTokenTransformerConventionTest { @@ -28,8 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels convention.Apply(model); // Assert - Assert.True(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var routeTokenTransformer)); - Assert.Equal(transformer, routeTokenTransformer); + Assert.Same(transformer, model.RouteParameterTransformer); } [Fact] @@ -49,7 +47,7 @@ namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels convention.Apply(model); // Assert - Assert.False(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out _)); + Assert.Null(model.RouteParameterTransformer); } private MethodInfo GetMethodInfo() diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/ApplicationModels/PageRouteTransformerConventionTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/ApplicationModels/PageRouteTransformerConventionTest.cs index 1fd04584b7..9dd1ac2a52 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/ApplicationModels/PageRouteTransformerConventionTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/ApplicationModels/PageRouteTransformerConventionTest.cs @@ -24,8 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels convention.Apply(model); // Assert - Assert.True(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var routeTokenTransformer)); - Assert.Equal(transformer, routeTokenTransformer); + Assert.Same(transformer, model.RouteParameterTransformer); } [Fact] @@ -41,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels convention.Apply(model); // Assert - Assert.False(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out _)); + Assert.Null(model.RouteParameterTransformer); } private class TestParameterTransformer : IOutboundParameterTransformer diff --git a/test/WebSites/RoutingWebSite/ControllerRouteTokenTransformerConvention.cs b/test/WebSites/RoutingWebSite/ControllerRouteTokenTransformerConvention.cs index d2b179a25b..5659c35a1c 100644 --- a/test/WebSites/RoutingWebSite/ControllerRouteTokenTransformerConvention.cs +++ b/test/WebSites/RoutingWebSite/ControllerRouteTokenTransformerConvention.cs @@ -8,12 +8,12 @@ using Microsoft.AspNetCore.Routing; namespace RoutingWebSite { - public class ControllerRouteTokenTransformerConvention : IApplicationModelConvention + public class ControllerRouteTokenTransformerConvention : RouteTokenTransformerConvention { private readonly Type _controllerType; - private readonly IOutboundParameterTransformer _parameterTransformer; public ControllerRouteTokenTransformerConvention(Type controllerType, IOutboundParameterTransformer parameterTransformer) + : base(parameterTransformer) { if (parameterTransformer == null) { @@ -21,18 +21,11 @@ namespace RoutingWebSite } _controllerType = controllerType; - _parameterTransformer = parameterTransformer; } - public void Apply(ApplicationModel application) + protected override bool ShouldApply(ActionModel action) { - foreach (var controller in application.Controllers.Where(c => c.ControllerType == _controllerType)) - { - foreach (var action in controller.Actions) - { - action.Properties[typeof(IOutboundParameterTransformer)] = _parameterTransformer; - } - } + return action.Controller.ControllerType == _controllerType; } } }