@@ -84,7 +84,7 @@ public VersionedApiExplorer( HttpConfiguration configuration )
84
84
/// <value>The <see cref="IDocumentationProvider">documentation provider</see> used to document APIs.</value>
85
85
public IDocumentationProvider DocumentationProvider
86
86
{
87
- get => documentationProvider ?? Configuration . Services . GetDocumentationProvider ( ) ;
87
+ get => documentationProvider ?? ( documentationProvider = Configuration . Services . GetDocumentationProvider ( ) ) ;
88
88
set => documentationProvider = value ;
89
89
}
90
90
@@ -258,7 +258,7 @@ protected virtual ApiDescriptionGroupCollection InitializeApiDescriptions()
258
258
var directRouteController = GetDirectRouteController ( directRouteCandidates , apiVersion ) ;
259
259
var apiDescriptionGroup = newApiDescriptions . GetOrAdd ( apiVersion , GetGroupName ) ;
260
260
var descriptionsFromRoute = ( directRouteController != null && directRouteCandidates != null ) ?
261
- ExploreDirectRoute ( directRouteController , directRouteCandidates , route , apiVersion ) :
261
+ ExploreDirectRouteControllers ( directRouteController , directRouteCandidates . Select ( c => c . ActionDescriptor ) . ToArray ( ) , route , apiVersion ) :
262
262
ExploreRouteControllers ( controllerMappings , route , apiVersion ) ;
263
263
264
264
// Remove ApiDescription that will lead to ambiguous action matching.
@@ -532,12 +532,24 @@ static HttpControllerDescriptor GetDirectRouteController( CandidateAction[] dire
532
532
return controllerDescriptor ;
533
533
}
534
534
535
- Collection < VersionedApiDescription > ExploreDirectRoute ( HttpControllerDescriptor controllerDescriptor , CandidateAction [ ] candidates , IHttpRoute route , ApiVersion apiVersion )
535
+ /// <summary>
536
+ /// Explores a controller that uses direct routes (aka "attribute" routing).
537
+ /// </summary>
538
+ /// <param name="controllerDescriptor">The <see cref="HttpControllerDescriptor">controller</see> to explore.</param>
539
+ /// <param name="candidateActionDescriptors">The <see cref="IReadOnlyList{T}">read-only list</see> of candidate <see cref="HttpActionDescriptor">actions</see> to explore.</param>
540
+ /// <param name="route">The <see cref="IHttpRoute">route</see> to explore.</param>
541
+ /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to explore.</param>
542
+ /// <returns>The <see cref="Collection{T}">collection</see> of discovered <see cref="VersionedApiDescription">API descriptions</see>.</returns>
543
+ protected virtual Collection < VersionedApiDescription > ExploreDirectRouteControllers (
544
+ HttpControllerDescriptor controllerDescriptor ,
545
+ IReadOnlyList < HttpActionDescriptor > candidateActionDescriptors ,
546
+ IHttpRoute route ,
547
+ ApiVersion apiVersion )
536
548
{
537
- Contract . Requires ( controllerDescriptor != null ) ;
538
- Contract . Requires ( candidates != null ) ;
539
- Contract . Requires ( route != null ) ;
540
- Contract . Requires ( apiVersion != null ) ;
549
+ Arg . NotNull ( controllerDescriptor , nameof ( controllerDescriptor ) ) ;
550
+ Arg . NotNull ( candidateActionDescriptors , nameof ( candidateActionDescriptors ) ) ;
551
+ Arg . NotNull ( route , nameof ( route ) ) ;
552
+ Arg . NotNull ( apiVersion , nameof ( apiVersion ) ) ;
541
553
Contract . Ensures ( Contract . Result < Collection < VersionedApiDescription > > ( ) != null ) ;
542
554
543
555
var descriptions = new Collection < VersionedApiDescription > ( ) ;
@@ -547,9 +559,8 @@ Collection<VersionedApiDescription> ExploreDirectRoute( HttpControllerDescriptor
547
559
return descriptions ;
548
560
}
549
561
550
- foreach ( var action in candidates )
562
+ foreach ( var actionDescriptor in candidateActionDescriptors )
551
563
{
552
- var actionDescriptor = action . ActionDescriptor ;
553
564
var actionName = actionDescriptor . ActionName ;
554
565
555
566
if ( ! ShouldExploreAction ( actionName , actionDescriptor , route , apiVersion ) )
@@ -571,11 +582,18 @@ Collection<VersionedApiDescription> ExploreDirectRoute( HttpControllerDescriptor
571
582
return descriptions ;
572
583
}
573
584
574
- Collection < VersionedApiDescription > ExploreRouteControllers ( IDictionary < string , HttpControllerDescriptor > controllerMappings , IHttpRoute route , ApiVersion apiVersion )
585
+ /// <summary>
586
+ /// Explores controllers that do not use direct routes (aka "attribute" routing)
587
+ /// </summary>
588
+ /// <param name="controllerMappings">The <see cref="IDictionary{TKey, TValue}">collection</see> of controller mappings.</param>
589
+ /// <param name="route">The <see cref="IHttpRoute">route</see> to explore.</param>
590
+ /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to explore.</param>
591
+ /// <returns>The <see cref="Collection{T}">collection</see> of discovered <see cref="VersionedApiDescription">API descriptions</see>.</returns>
592
+ protected virtual Collection < VersionedApiDescription > ExploreRouteControllers ( IDictionary < string , HttpControllerDescriptor > controllerMappings , IHttpRoute route , ApiVersion apiVersion )
575
593
{
576
- Contract . Requires ( controllerMappings != null ) ;
577
- Contract . Requires ( route != null ) ;
578
- Contract . Requires ( apiVersion != null ) ;
594
+ Arg . NotNull ( controllerMappings , nameof ( controllerMappings ) ) ;
595
+ Arg . NotNull ( route , nameof ( route ) ) ;
596
+ Arg . NotNull ( apiVersion , nameof ( apiVersion ) ) ;
579
597
Contract . Ensures ( Contract . Result < Collection < VersionedApiDescription > > ( ) != null ) ;
580
598
581
599
var apiDescriptions = new Collection < VersionedApiDescription > ( ) ;
@@ -706,7 +724,6 @@ void PopulateActionDescriptions(
706
724
Contract . Requires ( apiDescriptions != null ) ;
707
725
Contract . Requires ( apiVersion != null ) ;
708
726
709
- var apiDocumentation = DocumentationProvider ? . GetResponseDocumentation ( actionDescriptor ) ;
710
727
var parsedRoute = RouteParser . Parse ( localPath ) ;
711
728
var parameterDescriptions = CreateParameterDescriptions ( actionDescriptor , parsedRoute , route . Defaults ) ;
712
729
@@ -715,14 +732,17 @@ void PopulateActionDescriptions(
715
732
return ;
716
733
}
717
734
735
+ var documentation = DocumentationProvider ? . GetDocumentation ( actionDescriptor ) ;
718
736
var bodyParameter = parameterDescriptions . FirstOrDefault ( description => description . Source == FromBody ) ;
719
- var supportedRequestBodyFormatters = bodyParameter != null ?
737
+ var supportedRequestBodyFormatters =
738
+ bodyParameter != null ?
720
739
Configuration . Formatters . Where ( f => f . CanReadType ( bodyParameter . ParameterDescriptor . ParameterType ) ) :
721
740
Enumerable . Empty < MediaTypeFormatter > ( ) ;
722
741
723
742
var responseDescription = CreateResponseDescription ( actionDescriptor ) ;
724
743
var returnType = responseDescription . ResponseType ?? responseDescription . DeclaredType ;
725
- var supportedResponseFormatters = ( returnType != null && returnType != typeof ( void ) ) ?
744
+ var supportedResponseFormatters =
745
+ ( returnType != null && returnType != typeof ( void ) ) ?
726
746
Configuration . Formatters . Where ( f => f . CanWriteType ( returnType ) ) :
727
747
Enumerable . Empty < MediaTypeFormatter > ( ) ;
728
748
@@ -736,7 +756,7 @@ void PopulateActionDescriptions(
736
756
{
737
757
var apiDescription = new VersionedApiDescription ( )
738
758
{
739
- Documentation = apiDocumentation ,
759
+ Documentation = documentation ,
740
760
HttpMethod = method ,
741
761
RelativePath = finalPath ,
742
762
ActionDescriptor = actionDescriptor ,
@@ -753,9 +773,14 @@ void PopulateActionDescriptions(
753
773
}
754
774
}
755
775
756
- ResponseDescription CreateResponseDescription ( HttpActionDescriptor actionDescriptor )
776
+ /// <summary>
777
+ /// Creates a description for the response of the action.
778
+ /// </summary>
779
+ /// <param name="actionDescriptor">The <see cref="HttpActionDescriptor">action</see> to create a response description for.</param>
780
+ /// <returns>A new <see cref="ResponseDescription">response description</see>.</returns>
781
+ protected virtual ResponseDescription CreateResponseDescription ( HttpActionDescriptor actionDescriptor )
757
782
{
758
- Contract . Requires ( actionDescriptor != null ) ;
783
+ Arg . NotNull ( actionDescriptor , nameof ( actionDescriptor ) ) ;
759
784
Contract . Ensures ( Contract . Result < ResponseDescription > ( ) != null ) ;
760
785
761
786
var responseType = actionDescriptor . GetCustomAttributes < ResponseTypeAttribute > ( ) . FirstOrDefault ( ) ? . ResponseType ;
@@ -857,7 +882,7 @@ IList<ApiParameterDescription> CreateParameterDescriptions( HttpActionDescriptor
857
882
{
858
883
foreach ( var parameter in parameters )
859
884
{
860
- parameterDescriptions . Add ( CreateParameterDescriptionFromDescriptor ( parameter ) ) ;
885
+ parameterDescriptions . Add ( CreateParameterDescription ( parameter ) ) ;
861
886
}
862
887
}
863
888
}
@@ -894,16 +919,21 @@ static void AddUndeclaredRouteParameters( IParsedRoute parsedRoute, IDictionary<
894
919
}
895
920
}
896
921
897
- ApiParameterDescription CreateParameterDescriptionFromDescriptor ( HttpParameterDescriptor parameter )
922
+ /// <summary>
923
+ /// Creates a parameter description from the speicfied descriptor.
924
+ /// </summary>
925
+ /// <param name="parameterDescriptor">The <see cref="HttpParameterDescriptor">parameter descriptor</see> to create a description from.</param>
926
+ /// <returns>A new <see cref="ApiParameterDescription">parameter description</see>.</returns>
927
+ protected virtual ApiParameterDescription CreateParameterDescription ( HttpParameterDescriptor parameterDescriptor )
898
928
{
899
- Contract . Requires ( parameter != null ) ;
929
+ Arg . NotNull ( parameterDescriptor , nameof ( parameterDescriptor ) ) ;
900
930
Contract . Ensures ( Contract . Result < ApiParameterDescription > ( ) != null ) ;
901
931
902
932
return new ApiParameterDescription ( )
903
933
{
904
- ParameterDescriptor = parameter ,
905
- Name = parameter . Prefix ?? parameter . ParameterName ,
906
- Documentation = DocumentationProvider ? . GetDocumentation ( parameter ) ,
934
+ ParameterDescriptor = parameterDescriptor ,
935
+ Name = parameterDescriptor . Prefix ?? parameterDescriptor . ParameterName ,
936
+ Documentation = DocumentationProvider ? . GetDocumentation ( parameterDescriptor ) ,
907
937
Source = Unknown ,
908
938
} ;
909
939
}
@@ -913,7 +943,7 @@ ApiParameterDescription CreateParameterDescriptionFromBinding( HttpParameterBind
913
943
Contract . Requires ( parameterBinding != null ) ;
914
944
Contract . Ensures ( Contract . Result < ApiParameterDescription > ( ) != null ) ;
915
945
916
- var parameterDescription = CreateParameterDescriptionFromDescriptor ( parameterBinding . Descriptor ) ;
946
+ var parameterDescription = CreateParameterDescription ( parameterBinding . Descriptor ) ;
917
947
918
948
if ( parameterBinding . WillReadBody )
919
949
{
@@ -927,10 +957,6 @@ ApiParameterDescription CreateParameterDescriptionFromBinding( HttpParameterBind
927
957
return parameterDescription ;
928
958
}
929
959
930
- string GetApiDocumentation ( HttpActionDescriptor actionDescriptor ) => DocumentationProvider ? . GetDocumentation ( actionDescriptor ) ;
931
-
932
- string GetApiResponseDocumentation ( HttpActionDescriptor actionDescriptor ) => DocumentationProvider ? . GetResponseDocumentation ( actionDescriptor ) ;
933
-
934
960
static Collection < VersionedApiDescription > RemoveInvalidApiDescriptions ( Collection < VersionedApiDescription > apiDescriptions )
935
961
{
936
962
Contract . Requires ( apiDescriptions != null ) ;
0 commit comments