Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Csharp Client : Base URL from base class is not used in version 14.0.3, it was used in 14.0.2 #4764

Open
Arghan opened this issue Feb 5, 2024 · 8 comments

Comments

@Arghan
Copy link

Arghan commented Feb 5, 2024

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 :

image

Generated code version 14.0.2 :
It uses the BaseUrl property from the base class

var urlBuilder_ = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(BaseUrl)) urlBuilder_.Append(BaseUrl);
// Operation Path: "api/Consignee"
urlBuilder_.Append("api/Consignee");

Generated code version 14.0.3 :
It uses the private field _baseUrl

var urlBuilder_ = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
// Operation Path: "api/Consignee"
urlBuilder_.Append("api/Consignee");

Have a nice day.

@rm-code
Copy link

rm-code commented Feb 6, 2024

Just encountered the same issue after upgrading. Reverted back to the earlier version for now.

@codingdna2
Copy link
Contributor

Same here

@soligen2010
Copy link

I am having the same problem.

@soligen2010
Copy link

I think this was likely broken by PR #4691

@stevenvolckaert
Copy link

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.

@soligen2010
Copy link

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 -%}

@stevenvolckaert
Copy link

stevenvolckaert commented Mar 27, 2024

@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"
    }
  }
}

@franklixuefei
Copy link

franklixuefei commented Apr 11, 2024

@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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants