NSwag generates multiple functions with the same name when using OpenApi 3.0 JSON file
Asked Answered
S

2

7

I am trying to generate the client code in both .NET Core and TypeScript using NSwag CLI:

nswag run options.nswag

This works correctly for various Swagger 2.0 JSON files, but generates multiple functions with the exact same name for an OpenApi 3.0 JSON file.

My options.swag file has the following content for .NET (TypeScript is generated in a similar manner and suffers from the same issue):

{
  "runtime": "NetCore21",
  "defaultVariables": null,
  "documentGenerator": {
    "fromDocument": {
      "url": "https://somedomain.com/openapi.json",
      "output": null
    }
  },
  "codeGenerators": {
    "openApiToCSharpClient": {
      "clientBaseClass": null,
      "configurationClass": null,
      "generateClientClasses": true,
      "generateClientInterfaces": false,
      "injectHttpClient": true,
      "disposeHttpClient": true,
      "protectedMethods": [],
      "generateExceptionClasses": true,
      "exceptionClass": "ClientApiException",
      "wrapDtoExceptions": true,
      "useHttpClientCreationMethod": false,
      "httpClientType": "System.Net.Http.HttpClient",
      "useHttpRequestMessageCreationMethod": false,
      "useBaseUrl": true,
      "generateBaseUrlProperty": true,
      "generateSyncMethods": false,
      "exposeJsonSerializerSettings": false,
      "clientClassAccessModifier": "public",
      "typeAccessModifier": "public",
      "generateContractsOutput": false,
      "contractsNamespace": "DataLake",
      "contractsOutputFilePath": null,
      "parameterDateTimeFormat": "s",
      "generateUpdateJsonSerializerSettingsMethod": true,
      "serializeTypeInformation": false,
      "queryNullValue": "",
      "className": "{controller}Client",
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "additionalNamespaceUsages": [],
      "additionalContractNamespaceUsages": [],
      "generateOptionalParameters": false,
      "generateJsonMethods": false,
      "enforceFlagEnums": false,
      "parameterArrayType": "System.Collections.Generic.IEnumerable",
      "parameterDictionaryType": "System.Collections.Generic.IDictionary",
      "responseArrayType": "System.Collections.Generic.ICollection",
      "responseDictionaryType": "System.Collections.Generic.IDictionary",
      "wrapResponses": false,
      "wrapResponseMethods": [],
      "generateResponseClasses": true,
      "responseClass": "SwaggerResponse",
      "namespace": "SwaggerApiClientGenerationToolTest",
      "requiredPropertiesMustBeDefined": true,
      "dateType": "System.DateTimeOffset",
      "jsonConverters": null,
      "anyType": "object",
      "dateTimeType": "System.DateTimeOffset",
      "timeType": "System.TimeSpan",
      "timeSpanType": "System.TimeSpan",
      "arrayType": "System.Collections.Generic.ICollection",
      "arrayInstanceType": "System.Collections.ObjectModel.Collection",
      "dictionaryType": "System.Collections.Generic.IDictionary",
      "dictionaryInstanceType": "System.Collections.Generic.Dictionary",
      "arrayBaseType": "System.Collections.ObjectModel.Collection",
      "dictionaryBaseType": "System.Collections.Generic.Dictionary",
      "classStyle": "Poco",
      "generateDefaultValues": true,
      "generateDataAnnotations": true,
      "excludedTypeNames": [],
      "excludedParameterNames": [],
      "handleReferences": false,
      "generateImmutableArrayProperties": false,
      "generateImmutableDictionaryProperties": false,
      "jsonSerializerSettingsTransformationMethod": null,
      "inlineNamedArrays": false,
      "inlineNamedDictionaries": false,
      "inlineNamedTuples": true,
      "inlineNamedAny": false,
      "generateDtoTypes": true,
      "templateDirectory": null,
      "typeNameGeneratorType": null,
      "propertyNameGeneratorType": null,
      "enumNameGeneratorType": null,
      "serviceHost": null,
      "serviceSchemes": null,
      "output": "TheClient.cs"
    }
}

Is there a way for me to control function name generation so that adds some discriminant (similar to className which relies on {controller} token)?

Question: How to avoid NSwag generating multiple functions with the same name when using OpenApi 3.0 JSON file?

Shepperd answered 5/7, 2019 at 9:29 Comment(2)
Please also post your OpenAPI JSON file.Gantry
@Gantry - I will post it as soon as I am able to obfuscate it. Sounds strange, but I am unable to find an online tool to do this. Thanks.Shepperd
B
8

Without the OpenAPI.json file its hard to give an answer for your case. But you should be able to achieve different method naming by changing the OperationGenerationMode.

public enum OperationGenerationMode
{
    /// <summary>Multiple clients from the Swagger operation ID in the form '{controller}_{action}'.</summary>
    MultipleClientsFromOperationId,

    /// <summary>From path segments (operation name = last segment, client name = second to last segment).</summary>
    MultipleClientsFromPathSegments,

    /// <summary>From the first operation tag and path segments (operation name = last segment, client name = first operation tag).</summary>
    MultipleClientsFromFirstTagAndPathSegments,

    /// <summary>From the first operation tag and operation ID (operation name = operation ID, client name = first operation tag).</summary>
    MultipleClientsFromFirstTagAndOperationId,

    /// <summary>From the Swagger operation ID.</summary>
    SingleClientFromOperationId,

    /// <summary>From path segments suffixed by HTTP operation name</summary>
    SingleClientFromPathSegments,
}

https://github.com/RicoSuter/NSwag/blob/master/src/NSwag.Commands/Commands/CodeGeneration/OperationGenerationMode.cs

Barkley answered 11/10, 2019 at 9:42 Comment(1)
On command line this can be specifiied using, for example: nswag openapi2csclient /input:swagger.json /classname:WebAPIClient /namespace:MyNamespace /output:WebAPIClient.cs /OperationGenerationMode:SingleClientFromPathSegmentsNoctambulism
L
3

If you are using Swashbuckle to generate the API swagger metadata, what you can do is set the Name property of the Route or HttpPost/Get/Delete attribute to something like

Name="[Controller][Action]"

Then if you make sure the method names in C# are unique, and avoid underscores in the Name, then you get nice friendly NSwag client names too.

Lubumbashi answered 6/1, 2021 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.