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

error CS1501: No overload for method 'ToString' takes 1 arguments #4196

Open WimTenBrink opened 2 years ago

WimTenBrink commented 2 years ago

This is an error that I get since any 13.16.x and higher. The 13.15.10 is working fine. The error involves a .NET 6.0 Web API with the following method: public ActionResult<List<LogSession>> GetSessions([FromHeader] DateTime? before, [FromHeader] DateTime? after) As the specific fields need to be optional in my service, they need to be nullable. The Swagger generator generates this code:

        public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<LogSession>> GetSessionsAsync(System.DateTimeOffset? before, System.DateTimeOffset? after, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/Data/Sessions");

            var client_ = _httpClient;
            var disposeClient_ = false;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    if (before != null)
                        request_.Headers.TryAddWithoutValidation("before", ConvertToString(before?.ToString("s"), System.Globalization.CultureInfo.InvariantCulture));
                    if (after != null)
                        request_.Headers.TryAddWithoutValidation("after", ConvertToString(after?.ToString("s"), System.Globalization.CultureInfo.InvariantCulture));
                    request_.Method = new System.Net.Http.HttpMethod("GET");

The error applies to the ToString("s") for both the before and after parameters as the 13.15.10 version uses the method public string DateTimeOffset.ToString(string? format) for this. But the 13.16.0 version and higher use public override Nullable<T>.string? ToString() instead. The difference is this: 13.15 uses before?.ToString("s") 13.16 uses before.ToString("s") The 13.16 is missing the ? and thus the nullable method gets called. This won't work! The parameter is defined as System.DateTimeOffset? in both versions. And the only difference is the version of NSwat.ApiDescription.Client that I use. Downgrading to 13.15.10 and refreshing the code simply solves my issue, but I want to use the latest version.

brendangooden commented 1 year ago

Agree, I'm having the same issue. Downgrading to 13.15.10 doesn't work for me either - see below .nswag config

{ "runtime": "NetCore31", "defaultVariables": null, "documentGenerator": { "url": "https://raw.githubusercontent.com/XeroAPI/Xero-OpenAPI/master/xero_accounting.yaml", "output": null, "newLineBehavior": "Auto" } }, "codeGenerators": { "openApiToCSharpClient": { "clientBaseClass": "ApiClientBase ", "configurationClass": "IRestApiConfiguration", "generateClientClasses": true, "generateClientInterfaces": false, "clientBaseInterface": null, "injectHttpClient": true, "disposeHttpClient": true, "protectedMethods": [], "generateExceptionClasses": true, "exceptionClass": "XeroApiException ", "wrapDtoExceptions": true, "useHttpClientCreationMethod": false, "httpClientType": "System.Net.Http.HttpClient", "useHttpRequestMessageCreationMethod": true, "useBaseUrl": true, "generateBaseUrlProperty": false, "generateSyncMethods": false, "generatePrepareRequestAndProcessResponseAsAsyncMethods": false, "exposeJsonSerializerSettings": true, "clientClassAccessModifier": "public", "typeAccessModifier": "public", "generateContractsOutput": false, "contractsNamespace": null, "contractsOutputFilePath": null, "parameterDateTimeFormat": "s", "parameterDateFormat": "yyyy-MM-dd", "generateUpdateJsonSerializerSettingsMethod": true, "useRequestAndResponseSerializationSettings": false, "serializeTypeInformation": false, "queryNullValue": "null", "className": "XeroAccountingApi", "operationGenerationMode": "SingleClientFromOperationId", "additionalNamespaceUsages": [ "System.Net.Http" ], "additionalContractNamespaceUsages": [], "generateOptionalParameters": true, "generateJsonMethods": true, "enforceFlagEnums": true, "parameterArrayType": "System.Collections.Generic.IReadOnlyList", "parameterDictionaryType": "System.Collections.Generic.IDictionary", "responseArrayType": "System.Collections.Generic.IReadOnlyList", "responseDictionaryType": "System.Collections.Generic.IDictionary", "wrapResponses": false, "wrapResponseMethods": [], "generateResponseClasses": true, "responseClass": "SwaggerResponse", "requiredPropertiesMustBeDefined": true, "dateType": "System.DateTimeOffset", "jsonConverters": null, "anyType": "object", "dateTimeType": "System.DateTimeOffset", "timeType": "System.TimeSpan", "timeSpanType": "System.TimeSpan", "arrayType": "System.Collections.Generic.IReadOnlyList", "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": false, "generateDataAnnotations": true, "excludedTypeNames": [], "excludedParameterNames": [], "handleReferences": false, "generateImmutableArrayProperties": false, "generateImmutableDictionaryProperties": false, "jsonSerializerSettingsTransformationMethod": null, "inlineNamedArrays": false, "inlineNamedDictionaries": false, "inlineNamedTuples": true, "inlineNamedAny": false, "generateDtoTypes": true, "generateOptionalPropertiesAsNullable": true, "generateNullableReferenceTypes": false, "templateDirectory": null, "typeNameGeneratorType": null, "propertyNameGeneratorType": null, "enumNameGeneratorType": null, "serviceHost": null, "serviceSchemes": null, "newLineBehavior": "Auto" } } }

mdit commented 11 months ago

I've just had this with 13.20.0 and worked around it by adding an extension method in the same namespace as the generated code as follows:

public static class DateTimeOffsetExtensions
{
    public static string ToString(this System.DateTimeOffset? value, string format) => value?.ToString(format) ?? string.Empty;
}