@@ -403,16 +403,6 @@ private async Task<OpenApiResponse> GetResponseAsync(
403403                continue ; 
404404            } 
405405
406-             // MVC's ModelMetadata layer will set ApiParameterDescription.Type to string when the parameter 
407-             // is a parsable or convertible type. In this case, we want to use the actual model type 
408-             // to generate the schema instead of the string type. 
409-             var  targetType  =  parameter . Type  ==  typeof ( string )  &&  parameter . ModelMetadata . ModelType  !=  parameter . Type 
410-                 ?  parameter . ModelMetadata . ModelType 
411-                 :  parameter . Type ; 
412-             // If the type is null, then we're dealing with an inert 
413-             // route parameter that does not define a specific parameter type in the 
414-             // route handler or in the response. In this case, we default to a string schema. 
415-             targetType  ??=  typeof ( string ) ; 
416406            var  openApiParameter  =  new  OpenApiParameter 
417407            { 
418408                Name  =  parameter . Name , 
@@ -424,7 +414,7 @@ private async Task<OpenApiResponse> GetResponseAsync(
424414                    _ =>  throw  new  InvalidOperationException ( $ "Unsupported parameter source: { parameter . Source . Id } ") 
425415                } , 
426416                Required  =  IsRequired ( parameter ) , 
427-                 Schema  =  await  _componentService . GetOrCreateSchemaAsync ( targetType ,  scopedServiceProvider ,  schemaTransformers ,  parameter ,  cancellationToken :  cancellationToken ) , 
417+                 Schema  =  await  _componentService . GetOrCreateSchemaAsync ( GetTargetType ( description ,   parameter ) ,  scopedServiceProvider ,  schemaTransformers ,  parameter ,  cancellationToken :  cancellationToken ) , 
428418                Description  =  GetParameterDescriptionFromAttribute ( parameter ) 
429419            } ; 
430420
@@ -675,4 +665,34 @@ private async Task<OpenApiRequestBody> GetJsonRequestBody(
675665
676666        return  requestBody ; 
677667    } 
668+ 
669+     /// <remarks> 
670+     /// This method is used to determine the target type for a given parameter. The target type 
671+     /// is the actual type that should be used to generate the schema for the parameter. This is 
672+     /// necessary because MVC's ModelMetadata layer will set ApiParameterDescription.Type to string 
673+     /// when the parameter is a parsable or convertible type. In this case, we want to use the actual 
674+     /// model type to generate the schema instead of the string type. 
675+     /// </remarks> 
676+     /// <remarks> 
677+     /// This method will also check if no target type was resolved from the <see cref="ApiParameterDescription"/> 
678+     /// and default to a string schema. This will happen if we are dealing with an inert route parameter 
679+     /// that does not define a specific parameter type in the route handler or in the response. 
680+     /// </remarks> 
681+     private  static   Type  GetTargetType ( ApiDescription  description ,  ApiParameterDescription  parameter ) 
682+     { 
683+         var  bindingMetadata  =  description . ActionDescriptor . EndpointMetadata 
684+             . OfType < IParameterBindingMetadata > ( ) 
685+             . SingleOrDefault ( metadata =>  metadata . Name  ==  parameter . Name ) ; 
686+         var  parameterType  =  parameter . Type  is  not null 
687+             ?  Nullable . GetUnderlyingType ( parameter . Type )  ??  parameter . Type 
688+             :  parameter . Type ; 
689+         var  requiresModelMetadataFallback  =  parameterType  ==  typeof ( string )  &&  parameter . ModelMetadata . ModelType  !=  parameter . Type ; 
690+         // Enums are exempt because we want to set the OpenApiSchema.Enum field when feasible. 
691+         var  hasTryParse  =  bindingMetadata ? . HasTryParse  ==  true  &&  parameterType  is  not null  &&  ! parameterType . IsEnum ; 
692+         var  targetType  =  requiresModelMetadataFallback  ||  hasTryParse 
693+             ?  parameter . ModelMetadata . ModelType 
694+             :  parameter . Type ; 
695+         targetType  ??=  typeof ( string ) ; 
696+         return  targetType ; 
697+     } 
678698} 
0 commit comments