diff --git a/src/Http/Routing/src/ParameterPolicyActivator.cs b/src/Http/Routing/src/ParameterPolicyActivator.cs index 81da4d49e96e..020ea17842b8 100644 --- a/src/Http/Routing/src/ParameterPolicyActivator.cs +++ b/src/Http/Routing/src/ParameterPolicyActivator.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; @@ -86,6 +87,7 @@ public static T ResolveParameterPolicy( } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", Justification = "This type comes from the ConstraintMap.")] private static IParameterPolicy CreateParameterPolicy(IServiceProvider serviceProvider, Type parameterPolicyType, string argumentString) { ConstructorInfo activationConstructor = null; diff --git a/src/Http/Routing/src/RouteOptions.cs b/src/Http/Routing/src/RouteOptions.cs index 796554dd5800..85fd37cc3559 100644 --- a/src/Http/Routing/src/RouteOptions.cs +++ b/src/Http/Routing/src/RouteOptions.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Routing.Constraints; namespace Microsoft.AspNetCore.Routing @@ -82,38 +83,45 @@ public IDictionary ConstraintMap private static IDictionary GetDefaultConstraintMap() { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - // Type-specific constraints - { "int", typeof(IntRouteConstraint) }, - { "bool", typeof(BoolRouteConstraint) }, - { "datetime", typeof(DateTimeRouteConstraint) }, - { "decimal", typeof(DecimalRouteConstraint) }, - { "double", typeof(DoubleRouteConstraint) }, - { "float", typeof(FloatRouteConstraint) }, - { "guid", typeof(GuidRouteConstraint) }, - { "long", typeof(LongRouteConstraint) }, - - // Length constraints - { "minlength", typeof(MinLengthRouteConstraint) }, - { "maxlength", typeof(MaxLengthRouteConstraint) }, - { "length", typeof(LengthRouteConstraint) }, - - // Min/Max value constraints - { "min", typeof(MinRouteConstraint) }, - { "max", typeof(MaxRouteConstraint) }, - { "range", typeof(RangeRouteConstraint) }, - - // Regex-based constraints - { "alpha", typeof(AlphaRouteConstraint) }, - { "regex", typeof(RegexInlineRouteConstraint) }, - - {"required", typeof(RequiredRouteConstraint) }, - - // Files - { "file", typeof(FileNameRouteConstraint) }, - { "nonfile", typeof(NonFileNameRouteConstraint) }, - }; + var defaults = new Dictionary(StringComparer.OrdinalIgnoreCase); + + // Type-specific constraints + AddConstraint(defaults, "int"); + AddConstraint(defaults, "bool"); + AddConstraint(defaults, "datetime"); + AddConstraint(defaults, "decimal"); + AddConstraint(defaults, "double"); + AddConstraint(defaults, "float"); + AddConstraint(defaults, "guid"); + AddConstraint(defaults, "long"); + + // Length constraints + AddConstraint(defaults, "minlength"); + AddConstraint(defaults, "maxlength"); + AddConstraint(defaults, "length"); + + // Min/Max value constraints + AddConstraint(defaults, "min"); + AddConstraint(defaults, "max"); + AddConstraint(defaults, "range"); + + // Regex-based constraints + AddConstraint(defaults, "alpha"); + AddConstraint(defaults, "regex"); + + AddConstraint(defaults, "required"); + + // Files + AddConstraint(defaults, "file"); + AddConstraint(defaults, "nonfile"); + + return defaults; + } + + // This API could be exposed on RouteOptions + private static void AddConstraint<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]TConstraint>(Dictionary constraintMap, string text) where TConstraint : IRouteConstraint + { + constraintMap[text] = typeof(TConstraint); } } }