5
5
using System . Collections . Generic ;
6
6
using System . Globalization ;
7
7
using System . Linq ;
8
- using Microsoft . AspNetCore . Mvc . ActionConstraints ;
9
8
using Microsoft . AspNetCore . Mvc . ApplicationModels ;
10
9
using Microsoft . AspNetCore . Mvc . ModelBinding ;
11
10
using Microsoft . AspNetCore . WebHooks . Metadata ;
@@ -101,29 +100,45 @@ private void Apply(ActionModel action)
101
100
return ;
102
101
}
103
102
104
- var template = ChooseTemplate ( ) ;
105
- var selectors = action . Selectors ;
106
- if ( selectors . Count == 0 )
103
+ // Check for conflicting attribute routing attributes and constraints. Ignore the empty SelectorModel that
104
+ // DefaultApplicationModelProvider always creates.
105
+ var selectors = action . Selectors
106
+ . Concat ( action . Controller . Selectors )
107
+ . Where ( selectorModel => selectorModel . ActionConstraints . Count != 0 ||
108
+ selectorModel . AttributeRouteModel != null )
109
+ . ToArray ( ) ;
110
+ if ( selectors . Length != 0 )
107
111
{
108
- var selector = new SelectorModel ( ) ;
109
- selectors . Add ( selector ) ;
112
+ // For the error message, prefer an IRouteTemplateProvider over a constraint that is an Attribute.
113
+ // Prefer both over other constraints.
114
+ var conflictingAttribute = selectors
115
+ . Select ( model => ( object ) model . AttributeRouteModel ? . Attribute )
116
+ . Concat ( selectors . SelectMany ( model => model . ActionConstraints . OfType < Attribute > ( ) ) )
117
+ . Concat ( selectors . SelectMany ( model => model . ActionConstraints ) )
118
+ . FirstOrDefault ( ) ;
110
119
111
- AddTemplate ( attribute , template , selector ) ;
120
+ var message = string . Format (
121
+ CultureInfo . CurrentCulture ,
122
+ Resources . SelectorModelProvider_MixedRouteWithWebHookAttribute ,
123
+ attribute . GetType ( ) ,
124
+ conflictingAttribute ? . GetType ( ) ,
125
+ attribute . GetType ( ) . Name ) ;
126
+ throw new InvalidOperationException ( message ) ;
112
127
}
113
- else
128
+
129
+ // Set the template for given SelectorModel. Similar result to WebHookActionAttributeBase implementing
130
+ // IRouteTemplateProvider.
131
+ var selector = action . Selectors [ 0 ] ;
132
+ selector . AttributeRouteModel = new AttributeRouteModel
114
133
{
115
- for ( var i = 0 ; i < selectors . Count ; i ++ )
116
- {
117
- var selector = selectors [ i ] ;
118
- AddTemplate ( attribute , template , selector ) ;
119
- }
120
- }
134
+ Template = ChooseTemplate ( ) ,
135
+ } ;
121
136
122
137
var properties = action . Properties ;
123
- AddEventMapperConstraint ( properties , selectors ) ;
124
- AddEventNamesConstraint ( properties , selectors ) ;
125
- AddIdConstraint ( attribute , selectors ) ;
126
- AddReceiverExistsConstraint ( properties , selectors ) ;
138
+ AddEventNameMapperConstraint ( properties , selector ) ;
139
+ AddEventNamesConstraint ( properties , selector ) ;
140
+ AddIdConstraint ( attribute , selector ) ;
141
+ AddReceiverNameConstraint ( properties , selector ) ;
127
142
}
128
143
129
144
// Use a constant template since all WebHook constraints use the resulting route values and we have no
@@ -137,39 +152,7 @@ private static string ChooseTemplate()
137
152
return template ;
138
153
}
139
154
140
- // Set the template for given SelectorModel. Similar to WebHookActionAttributeBase implementing
141
- // IRouteTemplateProvider.
142
- private static void AddTemplate ( WebHookAttribute attribute , string template , SelectorModel selector )
143
- {
144
- if ( selector . AttributeRouteModel ? . Template != null )
145
- {
146
- var message = string . Format (
147
- CultureInfo . CurrentCulture ,
148
- Resources . RoutingProvider_MixedRouteWithWebHookAttribute ,
149
- attribute . GetType ( ) ,
150
- selector . AttributeRouteModel . Attribute ? . GetType ( ) ,
151
- attribute . GetType ( ) . Name ) ;
152
- throw new InvalidOperationException ( message ) ;
153
- }
154
-
155
- if ( selector . AttributeRouteModel == null )
156
- {
157
- selector . AttributeRouteModel = new AttributeRouteModel ( ) ;
158
- }
159
-
160
- selector . AttributeRouteModel . Template = template ;
161
- }
162
-
163
- private static void AddConstraint ( IActionConstraintMetadata constraint , IList < SelectorModel > selectors )
164
- {
165
- for ( var i = 0 ; i < selectors . Count ; i ++ )
166
- {
167
- var selector = selectors [ i ] ;
168
- selector . ActionConstraints . Add ( constraint ) ;
169
- }
170
- }
171
-
172
- private void AddEventMapperConstraint ( IDictionary < object , object > properties , IList < SelectorModel > selectors )
155
+ private void AddEventNameMapperConstraint ( IDictionary < object , object > properties , SelectorModel selector )
173
156
{
174
157
if ( properties . TryGetValue ( typeof ( IWebHookEventMetadata ) , out var eventMetadataObject ) )
175
158
{
@@ -183,11 +166,11 @@ private void AddEventMapperConstraint(IDictionary<object, object> properties, IL
183
166
constraint = new WebHookEventNameMapperConstraint ( _loggerFactory , _metadataProvider ) ;
184
167
}
185
168
186
- AddConstraint ( constraint , selectors ) ;
169
+ selector . ActionConstraints . Add ( constraint ) ;
187
170
}
188
171
}
189
172
190
- private void AddEventNamesConstraint ( IDictionary < object , object > properties , IList < SelectorModel > selectors )
173
+ private void AddEventNamesConstraint ( IDictionary < object , object > properties , SelectorModel selector )
191
174
{
192
175
if ( properties . TryGetValue ( typeof ( IWebHookEventSelectorMetadata ) , out var eventSourceMetadata ) )
193
176
{
@@ -196,7 +179,7 @@ private void AddEventNamesConstraint(IDictionary<object, object> properties, ILi
196
179
{
197
180
properties . TryGetValue ( typeof ( IWebHookPingRequestMetadata ) , out var pingRequestMetadataObject ) ;
198
181
199
- IActionConstraintMetadata constraint ;
182
+ WebHookEventNameConstraint constraint ;
200
183
if ( pingRequestMetadataObject == null )
201
184
{
202
185
constraint = new WebHookEventNameConstraint ( eventName ) ;
@@ -210,23 +193,21 @@ private void AddEventNamesConstraint(IDictionary<object, object> properties, ILi
210
193
constraint = new WebHookEventNameConstraint ( eventName , _metadataProvider ) ;
211
194
}
212
195
213
- AddConstraint ( constraint , selectors ) ;
196
+ selector . ActionConstraints . Add ( constraint ) ;
214
197
}
215
198
}
216
199
}
217
200
218
- private void AddIdConstraint ( WebHookAttribute attribute , IList < SelectorModel > selectors )
201
+ private void AddIdConstraint ( WebHookAttribute attribute , SelectorModel selector )
219
202
{
220
203
if ( attribute . Id != null )
221
204
{
222
205
var constraint = new WebHookIdConstraint ( attribute . Id ) ;
223
- AddConstraint ( constraint , selectors ) ;
206
+ selector . ActionConstraints . Add ( constraint ) ;
224
207
}
225
208
}
226
209
227
- private void AddReceiverExistsConstraint (
228
- IDictionary < object , object > properties ,
229
- IList < SelectorModel > selectors )
210
+ private void AddReceiverNameConstraint ( IDictionary < object , object > properties , SelectorModel selector )
230
211
{
231
212
var bodyTypeMetadataObject = properties [ typeof ( IWebHookBodyTypeMetadataService ) ] ;
232
213
@@ -240,7 +221,7 @@ private void AddReceiverExistsConstraint(
240
221
constraint = new WebHookReceiverNameConstraint ( _metadataProvider ) ;
241
222
}
242
223
243
- AddConstraint ( constraint , selectors ) ;
224
+ selector . ActionConstraints . Add ( constraint ) ;
244
225
}
245
226
}
246
227
}
0 commit comments