Generate NSwag client as part of the build
Asked Answered
H

1

10

I have a project that uses NSwag to generate a client and the contracts from a swagger file. I don't want these generated files to be tracked by git, so that when the project is built on the build server, it generates them as part of the build.

I've been playing around with MSBuild targets to try getting this to work, and it generates the files but then subsequently fails the build, because there's some other classes that reference the generated classes.

This is what I have in the csproj file at the moment:

<Target Name="NSwag" BeforeTargets="BeforeBuild;BeforeRebuild">
    <Exec Command="$(NSwagExe_Core21) run nswag.json /variables:Configuration=$(Configuration)" IgnoreExitCode="true" />
</Target>

Is this possible somehow?

Edit

Nswag spec here:

{
  "runtime": "NetCore21",
  "defaultVariables": null,
  "swaggerGenerator": {
    "fromSwagger": {
      "url": "swagger.json",
      "output": null
    }
  },
  "codeGenerators": {
    "swaggerToCSharpClient": {
      "clientBaseClass": "ClientBase", //name of your client base class
      "configurationClass": null,
      "generateClientClasses": true,
      "generateClientInterfaces": true,
      "generateDtoTypes": true,
      "injectHttpClient": true,
      "disposeHttpClient": true,
      "protectedMethods": [],
      "generateExceptionClasses": true,
      "exceptionClass": "SwaggerException",
      "wrapDtoExceptions": true,
      "useHttpClientCreationMethod": false,
      "httpClientType": "System.Net.Http.HttpClient",
      "useHttpRequestMessageCreationMethod": true, //allows you to add headers to each message
      "useBaseUrl": true,
      "generateBaseUrlProperty": true,
      "generateSyncMethods": false,
      "exposeJsonSerializerSettings": false,
      "clientClassAccessModifier": "internal", //make client generated client implementations internal
      "typeAccessModifier": "public", //make your models and client interfaces public
      "generateContractsOutput": true,
      "contractsNamespace": "MyNamspace.Client.Contracts",
      "contractsOutputFilePath": "Contracts.g.cs",
      "parameterDateTimeFormat": "s",
      "generateUpdateJsonSerializerSettingsMethod": true,
      "serializeTypeInformation": false,
      "queryNullValue": "",
      "className": "CorvetteClient",
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "additionalNamespaceUsages": [],
      "additionalContractNamespaceUsages": [],
      "generateOptionalParameters": false,
      "generateJsonMethods": true,
      "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": "MyNamespace.Client",
      "requiredPropertiesMustBeDefined": true,
      "dateType": "System.DateTimeOffset",
      "jsonConverters": null,
      "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": [],
      "handleReferences": false,
      "generateImmutableArrayProperties": false,
      "generateImmutableDictionaryProperties": false,
      "jsonSerializerSettingsTransformationMethod": null,
      "inlineNamedDictionaries": false,
      "inlineNamedTuples": true,
      "templateDirectory": null,
      "typeNameGeneratorType": null,
      "propertyNameGeneratorType": null,
      "enumNameGeneratorType": null,
      "serviceHost": null,
      "serviceSchemes": null,
      "output": "Client.g.cs"
    }
  }
}
Horizontal answered 18/12, 2019 at 13:39 Comment(3)
Where do you load the spec from? A file or the csproj?Roscoe
It's loaded from a file (updated post to include it)Horizontal
Thank you for providing me some configuration keys, like contractsNamespaceAsthenic
B
2

I manage to resolve same issue playing with clean target and include sources...

<!--Custom task to generate source code from OpenApi Specification before compilation-->
  <Target Name="GenerateSources" BeforeTargets="Compile">
        <Exec Command="$(NSwagExe_Core31) run config.nswag" />
  </Target>

   <!--Custom task to remove generate source code before clean project-->
   <Target Name="RemoveGenerateSources" BeforeTargets="CoreClean">
        <RemoveDir Directories="bin/debug/GeneratedSources" />
   </Target>

  <!--Register generated source code as project source code-->
  <ItemGroup>   
    <Compile Include="bin/debug/GeneratedSources/**/*.cs" />
  </ItemGroup>
Bark answered 27/4, 2020 at 17:52 Comment(1)
Unfortunately BeforeTargets="Compile" seems to trigger the command execution even when code analysis is running in the background, at least this is the case for the latest version of VS 2022.Mathur

© 2022 - 2024 — McMap. All rights reserved.