13
13
using System . Reflection ;
14
14
using System . Text ;
15
15
using System . Text . RegularExpressions ;
16
- using System . Threading . Tasks ;
17
16
#if WEBAPI
18
17
using System . Web . Http . Description ;
19
18
#endif
@@ -108,11 +107,7 @@ internal IReadOnlyList<string> ExpandNavigationPropertyLinkTemplate( string temp
108
107
109
108
for ( var i = 0 ; i < properties . Length ; i ++ )
110
109
{
111
- #if WEBAPI
112
- refLinks [ i ] = template . Replace ( token , properties [ i ] . Name ) ;
113
- #else
114
110
refLinks [ i ] = template . Replace ( token , properties [ i ] . Name , OrdinalIgnoreCase ) ;
115
- #endif
116
111
}
117
112
118
113
return refLinks ;
@@ -143,21 +138,37 @@ void AppendRoutePrefix( IList<string> segments )
143
138
144
139
void AppendPath ( IList < string > segments )
145
140
{
141
+ var controllerDescriptor = Context . ActionDescriptor
146
142
#if WEBAPI
147
- var controllerDescriptor = Context . ActionDescriptor . ControllerDescriptor ;
148
- #else
149
- var controllerDescriptor = Context . ActionDescriptor ;
143
+ . ControllerDescriptor
150
144
#endif
145
+ ;
151
146
152
147
if ( Context . IsAttributeRouted )
153
148
{
154
- #if WEBAPI
155
- var attributes = controllerDescriptor . GetCustomAttributes < ODataRoutePrefixAttribute > ( ) ;
156
- #else
157
- var attributes = controllerDescriptor . ControllerTypeInfo . GetCustomAttributes < ODataRoutePrefixAttribute > ( ) ;
149
+ var prefix = default ( string ) ;
150
+ var attribute = controllerDescriptor
151
+ #if ! WEBAPI
152
+ . ControllerTypeInfo
158
153
#endif
159
- var prefix = attributes . FirstOrDefault ( ) ? . Prefix ? . Trim ( '/' ) ;
154
+ . GetCustomAttributes < ODataRoutePrefixAttribute > ( )
155
+ . FirstOrDefault ( ) ;
160
156
157
+ if ( attribute is not null )
158
+ {
159
+ prefix = attribute . Prefix ? . Trim ( '/' ) ;
160
+ }
161
+ #if ! WEBAPI
162
+ else
163
+ {
164
+ var nativeEndpointRouting = Context . RouteTemplateProvider is not null ;
165
+
166
+ if ( nativeEndpointRouting )
167
+ {
168
+ prefix = controllerDescriptor . ControllerName ;
169
+ }
170
+ }
171
+ #endif
161
172
AppendPathFromAttributes ( segments , prefix ) ;
162
173
}
163
174
else
@@ -168,7 +179,7 @@ void AppendPath( IList<string> segments )
168
179
169
180
void AppendPathFromAttributes ( IList < string > segments , string ? prefix )
170
181
{
171
- var template = Context . RouteTemplate ;
182
+ var template = Context . RouteTemplate ? . Replace ( "[action]" , Context . ActionDescriptor . ActionName , OrdinalIgnoreCase ) ;
172
183
173
184
if ( Context . IsOperation && Context . RouteTemplateGeneration == Client && ! IsNullOrEmpty ( template ) )
174
185
{
@@ -550,11 +561,11 @@ IList<ApiParameterDescription> GetQueryParameters( IList<ApiParameterDescription
550
561
continue ;
551
562
}
552
563
564
+ var parameterType = parameter
553
565
#if API_EXPLORER
554
- var parameterType = parameter . ParameterDescriptor ? . ParameterType ;
555
- #else
556
- var parameterType = parameter . ParameterType ;
566
+ . ParameterDescriptor ?
557
567
#endif
568
+ . ParameterType ;
558
569
559
570
if ( parameterType == null || IsBuiltInParameter ( parameterType ) )
560
571
{
@@ -574,43 +585,59 @@ IList<ApiParameterDescription> GetQueryParameters( IList<ApiParameterDescription
574
585
575
586
bool TryAppendNavigationProperty ( StringBuilder builder , string name , IReadOnlyList < IEdmNavigationProperty > navigationProperties )
576
587
{
588
+ if ( navigationProperties . Count == 0 )
589
+ {
590
+ return false ;
591
+ }
592
+
577
593
// REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/PropertyRoutingConvention.cs
578
594
const string NavigationProperty = @"(?:Get|(?:Post|Put|Delete|Patch)To)(\w+)" ;
579
595
const string NavigationPropertyFromDeclaringType = NavigationProperty + @"From(\w+)" ;
580
596
var match = Regex . Match ( name , NavigationPropertyFromDeclaringType , RegexOptions . Singleline ) ;
597
+ string propertyName ;
581
598
582
- if ( ! match . Success )
599
+ if ( match . Success )
600
+ {
601
+ propertyName = match . Groups [ 2 ] . Value ;
602
+ }
603
+ else
583
604
{
584
605
match = Regex . Match ( name , NavigationProperty , RegexOptions . Singleline ) ;
585
606
586
- if ( ! match . Success )
607
+ if ( match . Success )
608
+ {
609
+ propertyName = match . Groups [ 1 ] . Value ;
610
+ }
611
+ else
587
612
{
588
613
return false ;
589
614
}
590
615
}
591
- else
616
+
617
+ for ( var i = 0 ; i < navigationProperties . Count ; i ++ )
592
618
{
593
- var navigationPropertyName = match . Groups [ 2 ] . Value ;
619
+ var navigationProperty = navigationProperties [ i ] ;
620
+
621
+ if ( ! navigationProperty . Name . Equals ( propertyName , OrdinalIgnoreCase ) )
622
+ {
623
+ continue ;
624
+ }
594
625
595
626
builder . Append ( '/' ) ;
596
627
597
628
if ( Context . Options . UseQualifiedNames )
598
629
{
599
- var navigationProperty = navigationProperties . First ( p => p . Name . Equals ( navigationPropertyName , OrdinalIgnoreCase ) ) ;
600
630
builder . Append ( navigationProperty . Type . ShortQualifiedName ( ) ) ;
601
631
}
602
632
else
603
633
{
604
- builder . Append ( navigationPropertyName ) ;
634
+ builder . Append ( propertyName ) ;
605
635
}
606
- }
607
636
608
- var propertyName = match . Groups [ 1 ] . Value ;
609
-
610
- builder . Append ( '/' ) ;
611
- builder . Append ( propertyName ) ;
637
+ return true ;
638
+ }
612
639
613
- return true ;
640
+ return false ;
614
641
}
615
642
616
643
#if API_EXPLORER
0 commit comments