@@ -22,32 +22,26 @@ public class ClientModelBuilder
2222 {
2323 private readonly ApiDescriptionGroupCollection apiExplorer ;
2424 private readonly GenerateClientOptions options ;
25- private readonly string [ ] additionalNamespaces ;
2625 private readonly Assembly webProjectAssembly ;
2726
2827 public ClientModelBuilder (
2928 ApiDescriptionGroupCollection apiExplorer ,
3029 GenerateClientOptions options ,
31- string [ ] additionalNamespaces ,
3230 Assembly webProjectAssembly )
3331 {
3432 this . apiExplorer = apiExplorer ;
3533 this . options = options ;
36- this . additionalNamespaces = additionalNamespaces ;
3734 this . webProjectAssembly = webProjectAssembly ;
3835 }
3936
40- public ClientCollection GetClientCollection ( )
37+ public List < Client > GetClientCollection ( )
4138 {
4239 var apiDescriptions = apiExplorer . Items
4340 . SelectMany ( i => i . Items )
4441 . ToList ( ) ;
4542
4643 FilterDescriptions ( apiDescriptions ) ;
4744
48- var allNamespaces = GetNamespaces ( apiDescriptions ) ;
49- var ambiguousTypes = GetAmbiguousTypes ( allNamespaces ) ;
50-
5145 var assemblyName = webProjectAssembly . GetName ( ) . Name ;
5246 var apiGroupsDescriptions = apiDescriptions . GroupBy ( i => GroupInfo . From ( i , assemblyName ) ) ;
5347
@@ -56,13 +50,11 @@ public ClientCollection GetClientCollection()
5650 var clients = apiGroupsDescriptions . Select ( apis =>
5751 GetClientModel (
5852 commonControllerNamespace : commonControllerNamespacePart ,
59- additionalNamespaces : additionalNamespaces ,
6053 controllerInfo : apis . Key ,
61- apiDescriptions : apis . ToList ( ) ,
62- ambiguousTypes : ambiguousTypes )
54+ apiDescriptions : apis . ToList ( ) )
6355 ) . ToList ( ) ;
6456
65- return new ClientCollection ( clients , ambiguousTypes ) ;
57+ return clients ;
6658 }
6759
6860 private void FilterDescriptions ( List < ApiDescription > apiDescriptions )
@@ -92,10 +84,8 @@ private void FilterDescriptions(List<ApiDescription> apiDescriptions)
9284
9385 internal Client GetClientModel (
9486 string commonControllerNamespace ,
95- string [ ] additionalNamespaces ,
9687 GroupInfo controllerInfo ,
97- List < ApiDescription > apiDescriptions ,
98- HashSet < Type > ambiguousTypes )
88+ List < ApiDescription > apiDescriptions )
9989 {
10090 apiDescriptions = HandleDuplicates ( apiDescriptions ) ;
10191
@@ -108,22 +98,11 @@ internal Client GetClientModel(
10898
10999 var clientNamespace = string . Join ( "." , new [ ] { options . Namespace } . Concat ( subPath ) ) ;
110100
111- var namespaces = GetNamespaces ( apiDescriptions , ambiguousTypes )
112- . Concat ( additionalNamespaces ) ;
113-
114- if ( options . AddCancellationTokenParameters )
115- namespaces = namespaces . Append ( "System.Threading" ) ;
116-
117- namespaces = namespaces
118- . OrderByDescending ( ns => ns . StartsWith ( "System" ) )
119- . ThenBy ( ns => ns ) ;
120-
121101 var methods = apiDescriptions . Select ( GetEndpointMethod ) . ToList ( ) ;
122102
123103 return new Client
124104 (
125105 location : Path . Combine ( subPath ) ,
126- importedNamespaces : namespaces . ToList ( ) ,
127106 @namespace : clientNamespace ,
128107 accessModifier : options . AccessModifier ,
129108 name : name ,
@@ -182,7 +161,7 @@ private List<Parameter> GetParameters(ApiDescription apiDescription)
182161
183162 parametersList . Add ( new Parameter (
184163 source : ParameterSource . File ,
185- type : typeof ( IFormFile ) ,
164+ type : typeof ( Stream ) ,
186165 name : parameterDescription . Name ,
187166 parameterName : name . ToCamelCase ( ) ,
188167 defaultValueLiteral : null ) ) ;
@@ -205,24 +184,39 @@ private List<Parameter> GetParameters(ApiDescription apiDescription)
205184 var name = parameterDescription . ParameterDescriptor ? . Name ?? "form" ;
206185 var formType = parameterDescription . ParameterDescriptor ? . ParameterType ?? typeof ( object ) ;
207186
208- var sameFormParameters = apiDescription . ParameterDescriptions . Skip ( i - 1 )
209- . TakeWhile ( d => d . ParameterDescriptor ? . ParameterType == formType && d . ParameterDescriptor ? . Name == name )
210- . ToArray ( ) ;
211-
212- // If form model has file parameters - we have to put it as separate parameters.
213- if ( ! sameFormParameters . Any ( p => p . Source . Id == "FormFile" ) )
187+ if ( formType == typeof ( IFormCollection ) )
214188 {
215189 parametersList . Add ( new Parameter (
216190 source : ParameterSource . Form ,
217- type : formType ,
191+ type : typeof ( Dictionary < string , string > ) ,
218192 name : parameterDescription . Name ,
219193 parameterName : name . ToCamelCase ( ) ,
220- defaultValueLiteral : "null" ) ) ;
221-
222- i += sameFormParameters . Length - 1 ;
194+ defaultValueLiteral : null ) ) ;
223195
224196 continue ;
225197 }
198+ else
199+ {
200+ var sameFormParameters = apiDescription . ParameterDescriptions . Skip ( i - 1 )
201+ . TakeWhile ( d => d . ParameterDescriptor ? . ParameterType == formType && d . ParameterDescriptor ? . Name == name )
202+ . ToArray ( ) ;
203+
204+ // If form model has file parameters - we have to put it as separate parameters.
205+ if ( ! sameFormParameters . Any ( p => p . Source . Id == "FormFile" ) )
206+ {
207+ parametersList . Add ( new Parameter (
208+ source : ParameterSource . Form ,
209+ type : formType ,
210+ name : parameterDescription . Name ,
211+ parameterName : name . ToCamelCase ( ) ,
212+ defaultValueLiteral : "null" ) ) ;
213+
214+ if ( sameFormParameters . Length > 0 )
215+ i += sameFormParameters . Length - 1 ;
216+
217+ continue ;
218+ }
219+ }
226220 }
227221
228222 if ( options . UseQueryModels
@@ -282,7 +276,9 @@ private List<Parameter> GetParameters(ApiDescription apiDescription)
282276
283277 parameterName = new string ( parameterName . Where ( c => char . IsLetterOrDigit ( c ) ) . ToArray ( ) ) ;
284278
285- var type = parameterDescription . ModelMetadata ? . ModelType ?? parameterDescription . Type ?? typeof ( string ) ;
279+ var type = parameterDescription . Source == BindingSource . FormFile
280+ ? typeof ( Stream )
281+ : parameterDescription . ModelMetadata ? . ModelType ?? parameterDescription . Type ?? typeof ( string ) ;
286282
287283 var defaultValue = GetDefaultValueLiteral ( parameterDescription , type ) ;
288284
@@ -313,30 +309,6 @@ private List<Parameter> GetParameters(ApiDescription apiDescription)
313309 return parametersList ;
314310 }
315311
316- private static HashSet < Type > GetAmbiguousTypes ( IEnumerable < string > namespaces )
317- {
318- var namespacesSet = namespaces . ToHashSet ( ) ;
319-
320- return AppDomain . CurrentDomain . GetAssemblies ( )
321- . Where ( a => ! a . IsDynamic )
322- . SelectMany ( a =>
323- {
324- try
325- {
326- return a . ExportedTypes ;
327- }
328- catch
329- {
330- return Array . Empty < Type > ( ) ;
331- }
332- } )
333- . Where ( t => t . DeclaringType == null && namespacesSet . Contains ( t . Namespace ! ) )
334- . GroupBy ( t => t . Name )
335- . Where ( g => g . Select ( t => t . Namespace ) . Distinct ( ) . Count ( ) > 1 )
336- . SelectMany ( g => g )
337- . ToHashSet ( ) ;
338- }
339-
340312 private static string ? GetXmlDoc ( ApiDescription apiDescription )
341313 {
342314 var xmlElement = ( apiDescription . ActionDescriptor as ControllerActionDescriptor ) ? . MethodInfo . GetXmlDocsElement ( ) ;
@@ -385,59 +357,6 @@ private static string GetCommonNamespacesPart(IEnumerable<IGrouping<GroupInfo, A
385357 return namespaces . GetCommonPart ( "." ) ;
386358 }
387359
388- private List < string > GetNamespaces ( IEnumerable < ApiDescription > apiDescriptions , HashSet < Type > ? ambiguousTypes = null )
389- {
390- var namespaces = new HashSet < string > ( ) ;
391-
392- foreach ( var apiDescription in apiDescriptions )
393- {
394- var responseType = GetResponseType ( apiDescription ) ;
395- AddForType ( responseType ) ;
396-
397- foreach ( var parameterDescription in apiDescription . ParameterDescriptions )
398- {
399- switch ( parameterDescription . Source . Id )
400- {
401- case "FormFile" :
402- // Skip FormFile, as it won't be present in result file
403- // (not needed for 3.1+)
404- break ;
405- case "Form" :
406- var hasFile = apiDescription . ParameterDescriptions
407- . Any ( d => d . ParameterDescriptor == parameterDescription . ParameterDescriptor && d . Source . Id == "FormFile" ) ;
408-
409- if ( ! hasFile )
410- AddForType ( parameterDescription . ParameterDescriptor . ParameterType ) ;
411-
412- break ;
413- case "Query" when options . UseQueryModels && parameterDescription . ModelMetadata ? . ContainerType != null :
414- AddForType ( parameterDescription . ModelMetadata . ContainerType ) ;
415- break ;
416- default :
417- AddForType ( parameterDescription . ModelMetadata ? . ModelType ?? parameterDescription . Type ) ;
418- break ;
419- }
420- }
421- }
422-
423- return namespaces . ToList ( ) ;
424-
425- void AddForType ( Type ? type )
426- {
427- if ( type != null && ! type . IsBuiltInType ( ) && ambiguousTypes ? . Contains ( type ) != true )
428- {
429- if ( type . Namespace != null )
430- namespaces . Add ( type . Namespace ) ;
431-
432- if ( type . IsGenericType )
433- {
434- foreach ( var typeArg in type . GetGenericArguments ( ) )
435- AddForType ( typeArg ) ;
436- }
437- }
438- }
439- }
440-
441360 private static string ? GetDefaultValueLiteral ( ApiParameterDescription parameter , Type parameterType )
442361 {
443362 var defaultValue = parameter . DefaultValue ;
0 commit comments