RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.78k stars 1.29k forks source link

how does one generate a c# client with camelCase naming conventions from a c# dll now that defaultPropertyNameHandling is deprecated? #1809

Closed blushingpenguin closed 5 years ago

blushingpenguin commented 5 years ago

In Startup.cs for the API:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerDocument(settings =>
    {
        settings.SerializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
        });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSwagger(settings =>
    {
        settings.Path = "/AppsApi/swagger.json";
    });
}

This works fine and generates swagger.json with camelCase properties, but generating an API with: node_modules/.bin/nswag run /runtime:NetCore22 /variables:Configuration=Release

produces an API with properties like:

        [Newtonsoft.Json.JsonProperty("IsGlobal", Required = Newtonsoft.Json.Required.Always)]
        public bool IsGlobal
        {

using nswag.json

{
  "runtime": "Default",
  "swaggerGenerator": {
    "webApiToSwagger": {
      "assemblyPaths": ["bin/$(Configuration)/netcoreapp2.2/win10-x64/publish/Blah.dll"]
    },
    "isAspNetCore": true,
    "output": null
  },
  "codeGenerators": {
    "swaggerToCSharpClient": {
      "generateClientClasses": true,
      "generateClientInterfaces": true,
      "generateDtoTypes": true,
      "injectHttpClient": true,
      "disposeHttpClient": true,
      "generateExceptionClasses": true,
      "exceptionClass": "ApiClientException",
      "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,
      "parameterDateTimeFormat": "s",
      "generateUpdateJsonSerializerSettingsMethod": true,
      "serializeTypeInformation": false,
      "queryNullValue": "",
      "className": "{controller}Client",
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "generateOptionalParameters": false,
      "generateJsonMethods": true,
      "parameterArrayType": "System.Collections.Generic.IEnumerable",
      "parameterDictionaryType": "System.Collections.Generic.IDictionary",
      "responseArrayType": "System.Collections.ObjectModel.ObservableCollection",
      "responseDictionaryType": "System.Collections.Generic.Dictionary",
      "wrapResponses": false,
      "generateResponseClasses": true,
      "responseClass": "SwaggerResponse",
      "namespace": "Blah.Client",
      "requiredPropertiesMustBeDefined": true,
      "dateType": "System.DateTime",
      "dateTimeType": "System.DateTime",
      "timeType": "System.TimeSpan",
      "timeSpanType": "System.TimeSpan",
      "arrayType": "System.Collections.ObjectModel.ObservableCollection",
      "dictionaryType": "System.Collections.Generic.Dictionary",
      "arrayBaseType": "System.Collections.ObjectModel.ObservableCollection",
      "dictionaryBaseType": "System.Collections.Generic.Dictionary",
      "classStyle": "Inpc",
      "generateDefaultValues": true,
      "generateDataAnnotations": true,
      "excludedTypeNames": [],
      "handleReferences": false,
      "generateImmutableArrayProperties": false,
      "generateImmutableDictionaryProperties": false,
      "output": "../Blah.Client/AppsClient.cs"
    }
  }
}

I guess nswag is using reflection to find the property details and hence can't see the camelCase serializer setting passed on to the middleware, but given that defaultPropertyNameHandling is deprecated (and also appears to have been removed from nswagstudio) how should one generate now generate an API with a camelCase naming convention?

Thanks,

Mark

RicoSuter commented 5 years ago

The problem is that you use AspNetCoreToSwaggerGenerator when starting the app and the legacy WebApiToSwaggerGenerator via CLI - this might give you different output. It is recommended to also use the AspNetCoreToSwaggerGenerator in CLI: https://github.com/RSuter/NSwag/wiki/AspNetCore-Middleware#generate-via-cli (this way the SerializerSettings are used from AddSwaggerDocument).

Another important point: The SerializerSettings should not be changed in AddSwaggerDocument as it is automatically retrieved from the ASP.NET Core system - i.e. change the config with:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddJsonOptions(opt =>
    {
        opt.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };
    });
}

so that the serialization actually matches the generated spec..