@@ -142,6 +142,7 @@ public virtual void OnProvidersExecuted( ApiDescriptionProviderContext context )
142
142
else
143
143
{
144
144
UpdateModelTypes ( result , matched ) ;
145
+ UpdateFunctionCollectionParameters ( result , matched ) ;
145
146
}
146
147
}
147
148
@@ -456,6 +457,75 @@ private void UpdateModelTypes( ApiDescription description, IODataRoutingMetadata
456
457
}
457
458
}
458
459
460
+ private static void UpdateFunctionCollectionParameters ( ApiDescription description , IODataRoutingMetadata metadata )
461
+ {
462
+ var parameters = description . ParameterDescriptions ;
463
+
464
+ if ( parameters . Count == 0 )
465
+ {
466
+ return ;
467
+ }
468
+
469
+ var function = default ( IEdmFunction ) ;
470
+ var mapping = default ( IDictionary < string , string > ) ;
471
+
472
+ for ( var i = 0 ; i < metadata . Template . Count ; i ++ )
473
+ {
474
+ var segment = metadata . Template [ i ] ;
475
+
476
+ if ( segment is FunctionSegmentTemplate func )
477
+ {
478
+ function = func . Function ;
479
+ mapping = func . ParameterMappings ;
480
+ break ;
481
+ }
482
+ else if ( segment is FunctionImportSegmentTemplate import )
483
+ {
484
+ function = import . FunctionImport . Function ;
485
+ mapping = import . ParameterMappings ;
486
+ break ;
487
+ }
488
+ }
489
+
490
+ if ( function is null || mapping is null )
491
+ {
492
+ return ;
493
+ }
494
+
495
+ var name = default ( string ) ;
496
+
497
+ foreach ( var parameter in function . Parameters )
498
+ {
499
+ if ( parameter . Type . IsCollection ( ) &&
500
+ mapping . TryGetValue ( parameter . Name , out name ) &&
501
+ parameters . SingleOrDefault ( p => p . Name == name ) is { } param )
502
+ {
503
+ param . Source = BindingSource . Path ;
504
+ break ;
505
+ }
506
+ }
507
+
508
+ var path = description . RelativePath ;
509
+
510
+ if ( string . IsNullOrEmpty ( name ) || string . IsNullOrEmpty ( path ) )
511
+ {
512
+ return ;
513
+ }
514
+
515
+ var span = name . AsSpan ( ) ;
516
+ Span < char > oldValue = stackalloc char [ name . Length + 2 ] ;
517
+ Span < char > newValue = stackalloc char [ name . Length + 4 ] ;
518
+
519
+ newValue [ 1 ] = oldValue [ 0 ] = '{' ;
520
+ newValue [ ^ 2 ] = oldValue [ ^ 1 ] = '}' ;
521
+ newValue [ 0 ] = '[' ;
522
+ newValue [ ^ 1 ] = ']' ;
523
+ span . CopyTo ( oldValue . Slice ( 1 , name . Length ) ) ;
524
+ span . CopyTo ( newValue . Slice ( 2 , name . Length ) ) ;
525
+
526
+ description . RelativePath = path . Replace ( oldValue . ToString ( ) , newValue . ToString ( ) , Ordinal ) ;
527
+ }
528
+
459
529
private sealed class ApiDescriptionComparer : IEqualityComparer < ApiDescription >
460
530
{
461
531
private readonly IEqualityComparer < string ? > comparer = StringComparer . OrdinalIgnoreCase ;
0 commit comments