Open Arghan opened 5 months ago
Just encountered the same issue after upgrading. Reverted back to the earlier version for now.
Same here
I am having the same problem.
I think this was likely broken by PR #4691
I have the same issue. We're using codeGenerators.openApiToCSharpClient.clientBaseClass
in nswag.json to specify a base class for each client. The base class contains a BaseUrl
property.
This works with all versions up until 14.0.0, but not with 14.0.1, 14.0.2, or 14.0.3.
I think the following changes will fix the issue, but I am not familiar with how this project is built to test it. Can someone test this and submit a pull request if it works?
Change file src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid
Change line 5 from
{% if UseBaseUrl -%}
to
{% if UseBaseUrl and !(HasConfigurationClass == true and GenerateBaseUrlProperty == false) -%}
and change line 292 from
{% if UseBaseUrl %}if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);{% endif %}
to
{% if HasConfigurationClass == true and GenerateBaseUrlProperty == false -%}
if (!string.IsNullOrEmpty(BaseUrl)) urlBuilder_.Append(BaseUrl);
{% else -%}
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
{% endif -%}
@RicoSuter I tried NSwag.MSBuild.14.0.7
which was just released. This version produces the same issue: BaseUrl
from a base class is not used any more.
My nswag.json below; I'm using openApiToCSharpClient
to generate the C# code to call my REST API.
Would there be any workaround?
I'm currently using PrepareRequest(HttpClient, HttpRequestMessage, string)
to set the HttpClient.BaseAddress
property (HttpClientSettings
is my configuration class, specified by codeGenerators.openApiToCSharpClient.configurationClass
); is this the recommended way to set the base URL in NSwag v14?
public partial class SessionEndpointsClient
{
partial void PrepareRequest(HttpClient client, HttpRequestMessage request, string url)
{
client.BaseAddress = new Uri(this.HttpClientSettings.BaseUrl);
}
Edit: I'm now configuring the HttpClient
when I register it with the IServiceCollection
:
serviceCollection
.AddTransient<HttpClientSettings>(serviceProvider =>
configuration.GetSection(HttpClientSettings.FullTypeName).Get<HttpClientSettings>()!
);
serviceCollection
.AddHttpClient(
name: HttpClientSettings.HttpClientName,
configureClient: (serviceProvider, httpClient) =>
{
var httpClientSettings = serviceProvider.GetRequiredService<HttpClientSettings>();
httpClient.BaseAddress = new Uri(httpClientSettings.BaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(httpClientSettings.TimeoutInSeconds);
// ...
}
);
serviceCollection.AddHttpClient<SessionEndpointsClient>(HttpClientSettings.HttpClientName);
With this central configuration, implementing PrepareRequest(HttpClient, HttpRequestMessage, string)
in every client is no longer necessary.
This is good enough for us, however if anyone has other ideas, I'd be curious to read about them.
nswag.json below
{
"runtime": "Net70",
"defaultVariables": null,
"documentGenerator": {
"aspNetCoreToOpenApi": {
"project": "../Skarabee.DocumentSigning.CoreService/Skarabee.DocumentSigning.CoreService.csproj",
"msBuildProjectExtensionsPath": null,
"configuration": null,
"runtime": null,
"targetFramework": null,
"noBuild": true,
"msBuildOutputPath": null,
"verbose": true,
"workingDirectory": null,
"requireParametersWithoutDefault": true,
"apiGroupNames": null,
"defaultPropertyNameHandling": "Default",
"defaultReferenceTypeNullHandling": "Null",
"defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
"defaultResponseReferenceTypeNullHandling": "NotNull",
"generateOriginalParameterNames": true,
"defaultEnumHandling": "Integer",
"flattenInheritanceHierarchy": true,
"generateKnownTypes": true,
"generateEnumMappingDescription": false,
"generateXmlObjects": false,
"generateAbstractProperties": false,
"generateAbstractSchemas": false,
"ignoreObsoleteProperties": false,
"allowReferencesWithProperties": false,
"useXmlDocumentation": true,
"resolveExternalXmlDocumentation": true,
"excludedTypeNames": [
"Exception"
],
"serviceHost": null,
"serviceBasePath": null,
"serviceSchemes": [],
"infoTitle": "My Title",
"infoDescription": null,
"infoVersion": "1.0.0",
"documentTemplate": null,
"documentProcessorTypes": [],
"operationProcessorTypes": [],
"typeNameGeneratorType": null,
"schemaNameGeneratorType": null,
"contractResolverType": null,
"serializerSettingsType": null,
"useDocumentProvider": true,
"documentName": "v1",
"aspNetCoreEnvironment": null,
"createWebHostBuilderMethod": null,
"startupType": null,
"allowNullableBodyParameters": true,
"useHttpAttributeNameAsOperationId": false,
"output": null,
"outputType": "OpenApi3",
"newLineBehavior": "Auto",
"assemblyPaths": [],
"assemblyConfig": null,
"referencePaths": [],
"useNuGetCache": false
}
},
"codeGenerators": {
"openApiToCSharpClient": {
"clientBaseClass": "HttpServiceClientBase<HttpClientSettings>",
"configurationClass": "HttpClientSettings",
"generateClientClasses": true,
"generateClientInterfaces": false,
"clientBaseInterface": null,
"injectHttpClient": true,
"disposeHttpClient": false,
"protectedMethods": [
"ProviderEndpointsClient.GetProviderAsync"
],
"generateExceptionClasses": true,
"exceptionClass": "HttpServiceException",
"wrapDtoExceptions": true,
"useHttpClientCreationMethod": false,
"httpClientType": "System.Net.Http.HttpClient",
"useHttpRequestMessageCreationMethod": true,
"useBaseUrl": true,
"generateBaseUrlProperty": false,
"generateSyncMethods": true,
"generatePrepareRequestAndProcessResponseAsAsyncMethods": false,
"exposeJsonSerializerSettings": false,
"clientClassAccessModifier": "public",
"typeAccessModifier": "public",
"generateContractsOutput": false,
"contractsNamespace": null,
"contractsOutputFilePath": null,
"parameterDateTimeFormat": "o",
"parameterDateFormat": "yyyy-MM-dd",
"generateUpdateJsonSerializerSettingsMethod": true,
"useRequestAndResponseSerializationSettings": false,
"serializeTypeInformation": false,
"queryNullValue": "",
"className": "{controller}Client",
"operationGenerationMode": "MultipleClientsFromOperationId",
"additionalNamespaceUsages": [
"System"
],
"additionalContractNamespaceUsages": [],
"generateOptionalParameters": false,
"generateJsonMethods": false,
"enforceFlagEnums": false,
"parameterArrayType": "System.Collections.Generic.IEnumerable",
"parameterDictionaryType": "System.Collections.Generic.IDictionary",
"responseArrayType": "System.Collections.Generic.IList",
"responseDictionaryType": "System.Collections.Generic.IDictionary",
"wrapResponses": false,
"wrapResponseMethods": [],
"generateResponseClasses": true,
"responseClass": "HttpServiceResponse",
"namespace": "Skarabee.DocumentSigning.CoreService",
"requiredPropertiesMustBeDefined": true,
"dateType": "System.DateTimeOffset",
"jsonConverters": null,
"anyType": "object",
"dateTimeType": "System.DateTimeOffset",
"timeType": "System.TimeSpan",
"timeSpanType": "System.TimeSpan",
"arrayType": "System.Collections.Generic.IList",
"arrayInstanceType": "System.Collections.Generic.List",
"dictionaryType": "System.Collections.Generic.IDictionary",
"dictionaryInstanceType": "System.Collections.Generic.Dictionary",
"arrayBaseType": "System.Collections.Generic.List",
"dictionaryBaseType": "System.Collections.Generic.Dictionary",
"classStyle": "Poco",
"jsonLibrary": "NewtonsoftJson",
"generateDefaultValues": true,
"generateDataAnnotations": true,
"excludedTypeNames": [
"Exception"
],
"excludedParameterNames": [],
"handleReferences": false,
"generateImmutableArrayProperties": false,
"generateImmutableDictionaryProperties": false,
"jsonSerializerSettingsTransformationMethod": null,
"inlineNamedArrays": false,
"inlineNamedDictionaries": false,
"inlineNamedTuples": true,
"inlineNamedAny": false,
"generateDtoTypes": true,
"generateOptionalPropertiesAsNullable": false,
"generateNullableReferenceTypes": false,
"templateDirectory": null,
"typeNameGeneratorType": null,
"propertyNameGeneratorType": null,
"enumNameGeneratorType": null,
"serviceHost": null,
"serviceSchemes": null,
"output": "Skarabee.DocumentSigning.CoreService.Clients.g.cs",
"newLineBehavior": "Auto"
}
}
}
@RicoSuter We are also hitting the same. If there is a new way to dynamically specify the BaseUrl, please let us know. It is currently blocking us from bumping up to 14.0.7 in our projects. Thanks!
14.0.8 still also has a big problem with the constructor logic.
If you are using BaseUrl property but you are also using a configuration class the generated code for the constructor comes out like this.
public MyClass (MyConfig configuration) : base(configuration)
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
{
BaseUrl = baseUrl;
}
It still runs the line to assign the baseUrl property but its not included in the constructor arguments. This results in non-compilable code. The constructor arguments generator needs the same conditions as the code that outputs the assignment line
Hello,
I think there is an issue with the version 14.0.3, the BaseUrl property from the base client is not used anymore :
Here are the settings I am using :
Generated code version 14.0.2 : It uses the BaseUrl property from the base class
Generated code version 14.0.3 : It uses the private field _baseUrl
Have a nice day.