@@ -100,7 +100,13 @@ internal ODataRouteActionType GetActionType( ControllerActionDescriptor action )
100
100
}
101
101
else if ( Operation == null )
102
102
{
103
- if ( IsActionOrFunction ( EntitySet , Singleton , action . ActionName , GetHttpMethods ( action ) ) )
103
+ var httpMethods = GetHttpMethods ( action ) ;
104
+
105
+ if ( IsCast ( EdmModel , EntitySet , action . ActionName , httpMethods ) )
106
+ {
107
+ return ODataRouteActionType . EntitySet ;
108
+ }
109
+ else if ( IsActionOrFunction ( EntitySet , Singleton , action . ActionName , httpMethods ) )
104
110
{
105
111
return ODataRouteActionType . Unknown ;
106
112
}
@@ -122,6 +128,52 @@ internal ODataRouteActionType GetActionType( ControllerActionDescriptor action )
122
128
return ODataRouteActionType . UnboundOperation ;
123
129
}
124
130
131
+ static bool IsCast ( IEdmModel model , IEdmEntitySet ? entitySet , string actionName , IEnumerable < string > methods )
132
+ {
133
+ using var iterator = methods . GetEnumerator ( ) ;
134
+
135
+ if ( ! iterator . MoveNext ( ) )
136
+ {
137
+ return false ;
138
+ }
139
+
140
+ var method = iterator . Current ;
141
+
142
+ if ( iterator . MoveNext ( ) )
143
+ {
144
+ return false ;
145
+ }
146
+
147
+ if ( entitySet == null )
148
+ {
149
+ return false ;
150
+ }
151
+
152
+ var entity = entitySet . EntityType ( ) ;
153
+
154
+ const string ActionMethod = "Post" ;
155
+ const string FunctionMethod = "Get" ;
156
+
157
+ if ( ( FunctionMethod . Equals ( method , OrdinalIgnoreCase ) ||
158
+ ActionMethod . Equals ( method , OrdinalIgnoreCase ) ) &&
159
+ actionName != ActionMethod )
160
+ {
161
+ foreach ( var derivedType in model . FindAllDerivedTypes ( entity ) . OfType < EdmEntityType > ( ) )
162
+ {
163
+ var fromTypeName = "From" + derivedType . Name ;
164
+
165
+ if ( actionName . StartsWith ( method + fromTypeName , OrdinalIgnoreCase ) ||
166
+ actionName . StartsWith ( method + entitySet . Name + fromTypeName , OrdinalIgnoreCase ) ||
167
+ actionName . StartsWith ( method + derivedType . Name , OrdinalIgnoreCase ) )
168
+ {
169
+ return true ;
170
+ }
171
+ }
172
+ }
173
+
174
+ return false ;
175
+ }
176
+
125
177
// Slash became the default 4/18/2018
126
178
// REF: https://github.com/OData/WebApi/pull/1393
127
179
static ODataUrlKeyDelimiter UrlKeyDelimiterOrDefault ( ODataUrlKeyDelimiter ? urlKeyDelimiter ) => urlKeyDelimiter ?? Slash ;
0 commit comments