@@ -182,7 +182,13 @@ internal ODataRouteActionType GetActionType( HttpActionDescriptor action )
182
182
}
183
183
else if ( Operation == null )
184
184
{
185
- if ( IsActionOrFunction ( EntitySet , Singleton , action . ActionName , GetHttpMethods ( action ) ) )
185
+ var httpMethods = GetHttpMethods ( action ) ;
186
+
187
+ if ( IsCast ( EdmModel , EntitySet , action . ActionName , httpMethods ) )
188
+ {
189
+ return ODataRouteActionType . EntitySet ;
190
+ }
191
+ else if ( IsActionOrFunction ( EntitySet , Singleton , action . ActionName , httpMethods ) )
186
192
{
187
193
return ODataRouteActionType . Unknown ;
188
194
}
@@ -204,6 +210,52 @@ internal ODataRouteActionType GetActionType( HttpActionDescriptor action )
204
210
return ODataRouteActionType . UnboundOperation ;
205
211
}
206
212
213
+ private static bool IsCast ( IEdmModel model , IEdmEntitySet ? entitySet , string actionName , IEnumerable < string > methods )
214
+ {
215
+ using var iterator = methods . GetEnumerator ( ) ;
216
+
217
+ if ( ! iterator . MoveNext ( ) )
218
+ {
219
+ return false ;
220
+ }
221
+
222
+ var method = iterator . Current ;
223
+
224
+ if ( iterator . MoveNext ( ) )
225
+ {
226
+ return false ;
227
+ }
228
+
229
+ if ( entitySet == null )
230
+ {
231
+ return false ;
232
+ }
233
+
234
+ var entity = entitySet . EntityType ( ) ;
235
+
236
+ const string ActionMethod = "Post" ;
237
+ const string FunctionMethod = "Get" ;
238
+
239
+ if ( ( FunctionMethod . Equals ( method , OrdinalIgnoreCase ) ||
240
+ ActionMethod . Equals ( method , OrdinalIgnoreCase ) ) &&
241
+ actionName != ActionMethod )
242
+ {
243
+ foreach ( var derivedType in model . FindAllDerivedTypes ( entity ) . OfType < EdmEntityType > ( ) )
244
+ {
245
+ var fromTypeName = "From" + derivedType . Name ;
246
+
247
+ if ( actionName . StartsWith ( method + fromTypeName , OrdinalIgnoreCase ) ||
248
+ actionName . StartsWith ( method + entitySet . Name + fromTypeName , OrdinalIgnoreCase ) ||
249
+ actionName . StartsWith ( method + derivedType . Name , OrdinalIgnoreCase ) )
250
+ {
251
+ return true ;
252
+ }
253
+ }
254
+ }
255
+
256
+ return false ;
257
+ }
258
+
207
259
// Slash became the default 4/18/2018
208
260
// REF: https://github.com/OData/WebApi/pull/1393
209
261
private static ODataUrlKeyDelimiter UrlKeyDelimiterOrDefault ( ODataUrlKeyDelimiter ? urlKeyDelimiter ) => urlKeyDelimiter ?? Slash ;
0 commit comments