|
4 | 4 | using System;
|
5 | 5 | using System.Collections.Generic;
|
6 | 6 | using System.Diagnostics;
|
| 7 | +using System.Diagnostics.CodeAnalysis; |
7 | 8 | using Microsoft.AspNetCore.Routing.Constraints;
|
8 | 9 |
|
9 | 10 | namespace Microsoft.AspNetCore.Routing
|
@@ -82,38 +83,45 @@ public IDictionary<string, Type> ConstraintMap
|
82 | 83 |
|
83 | 84 | private static IDictionary<string, Type> GetDefaultConstraintMap()
|
84 | 85 | {
|
85 |
| - return new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase) |
86 |
| - { |
87 |
| - // Type-specific constraints |
88 |
| - { "int", typeof(IntRouteConstraint) }, |
89 |
| - { "bool", typeof(BoolRouteConstraint) }, |
90 |
| - { "datetime", typeof(DateTimeRouteConstraint) }, |
91 |
| - { "decimal", typeof(DecimalRouteConstraint) }, |
92 |
| - { "double", typeof(DoubleRouteConstraint) }, |
93 |
| - { "float", typeof(FloatRouteConstraint) }, |
94 |
| - { "guid", typeof(GuidRouteConstraint) }, |
95 |
| - { "long", typeof(LongRouteConstraint) }, |
96 |
| - |
97 |
| - // Length constraints |
98 |
| - { "minlength", typeof(MinLengthRouteConstraint) }, |
99 |
| - { "maxlength", typeof(MaxLengthRouteConstraint) }, |
100 |
| - { "length", typeof(LengthRouteConstraint) }, |
101 |
| - |
102 |
| - // Min/Max value constraints |
103 |
| - { "min", typeof(MinRouteConstraint) }, |
104 |
| - { "max", typeof(MaxRouteConstraint) }, |
105 |
| - { "range", typeof(RangeRouteConstraint) }, |
106 |
| - |
107 |
| - // Regex-based constraints |
108 |
| - { "alpha", typeof(AlphaRouteConstraint) }, |
109 |
| - { "regex", typeof(RegexInlineRouteConstraint) }, |
110 |
| - |
111 |
| - {"required", typeof(RequiredRouteConstraint) }, |
112 |
| - |
113 |
| - // Files |
114 |
| - { "file", typeof(FileNameRouteConstraint) }, |
115 |
| - { "nonfile", typeof(NonFileNameRouteConstraint) }, |
116 |
| - }; |
| 86 | + var defaults = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase); |
| 87 | + |
| 88 | + // Type-specific constraints |
| 89 | + AddConstraint<IntRouteConstraint>(defaults, "int"); |
| 90 | + AddConstraint<BoolRouteConstraint>(defaults, "bool"); |
| 91 | + AddConstraint<DateTimeRouteConstraint>(defaults, "datetime"); |
| 92 | + AddConstraint<DecimalRouteConstraint>(defaults, "decimal"); |
| 93 | + AddConstraint<DoubleRouteConstraint>(defaults, "double"); |
| 94 | + AddConstraint<FloatRouteConstraint>(defaults, "float"); |
| 95 | + AddConstraint<GuidRouteConstraint>(defaults, "guid"); |
| 96 | + AddConstraint<LongRouteConstraint>(defaults, "long"); |
| 97 | + |
| 98 | + // Length constraints |
| 99 | + AddConstraint<MinLengthRouteConstraint>(defaults, "minlength"); |
| 100 | + AddConstraint<MaxLengthRouteConstraint>(defaults, "maxlength"); |
| 101 | + AddConstraint<LengthRouteConstraint>(defaults, "length"); |
| 102 | + |
| 103 | + // Min/Max value constraints |
| 104 | + AddConstraint<MinRouteConstraint>(defaults, "min"); |
| 105 | + AddConstraint<MaxRouteConstraint>(defaults, "max"); |
| 106 | + AddConstraint<RangeRouteConstraint>(defaults, "range"); |
| 107 | + |
| 108 | + // Regex-based constraints |
| 109 | + AddConstraint<AlphaRouteConstraint>(defaults, "alpha"); |
| 110 | + AddConstraint<RegexInlineRouteConstraint>(defaults, "regex"); |
| 111 | + |
| 112 | + AddConstraint<RequiredRouteConstraint>(defaults, "required"); |
| 113 | + |
| 114 | + // Files |
| 115 | + AddConstraint<FileNameRouteConstraint>(defaults, "file"); |
| 116 | + AddConstraint<NonFileNameRouteConstraint>(defaults, "nonfile"); |
| 117 | + |
| 118 | + return defaults; |
| 119 | + } |
| 120 | + |
| 121 | + // This API could be exposed on RouteOptions |
| 122 | + private static void AddConstraint<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]TConstraint>(Dictionary<string, Type> constraintMap, string text) where TConstraint : IRouteConstraint |
| 123 | + { |
| 124 | + constraintMap[text] = typeof(TConstraint); |
117 | 125 | }
|
118 | 126 | }
|
119 | 127 | }
|
0 commit comments