Search code examples
c#swaggeropenapinswag

Nullable DataTime/DateTimeOffset parameter in Header causing error in NSwag generated client


We have an Open Api specification that we are using to generate an Http client using the NSwag openapi2csclient from MSBuild.

<Target Name="NSwag" BeforeTargets="BeforeBuild">
    <Exec Command="$(NSwagExe) openapi2csclient /OperationGenerationMode:MultipleClientsFromFirstTagAndPathSegments /UseBaseUrl:false /namespace:FooSpace /GenerateOptionalParameters:true /GenerateClientInterfaces:true /input:Clients/FooSpace/FooSpace-OpenApi.json /output:Clients/FooSpace/FooSpaceClient.cs" />
</Target>

It seems however that there is a problem when adding a non-required DateTime/DateTimeOffset as a parameter to a header for any method as this seems to be generated as a Nullable DateTime?/DateTimeOffset? in the Client-code.

The relevant parameter in the Open Api document:

{
    "name": "Updated",
    "in": "header",
    "schema": {
        "type": "string",
        "format": "date-time"
    }
}

The generated code-snippet that is failing:

if (updatedHeader != null)
    request_.Headers.TryAddWithoutValidation("Updated", ConvertToString(updatedHeader.ToString("s"), System.Globalization.CultureInfo.InvariantCulture));

The above code snippets throws the error:

No overload for method 'ToString' takes 1 arguments

Query parameters with the same parameter are working fine as the Nullable's Value property is used instead in the generated code:

if (updatedQuery != null)
{
    urlBuilder_.Append(System.Uri.EscapeDataString("Updated") + "=").Append(System.Uri.EscapeDataString(updatedQuery.Value.ToString("s", System.Globalization.CultureInfo.InvariantCulture))).Append("&");
}

Is there any workaround for this?


Solution

  • The source of the problem was that the liquid template in the NSwag source code (link) only adds a null-conditional operator when the parameter is set to Nullable as such: {% if parameter.IsNullable %}?{% endif %}.

    The problem is that when defining an optional parameter (as was the case for us) NSwag does not consider it nullable by default. Thus, we solved this by adding a line of code explicitly setting value type to Nullable like this:

    if (property.PropertyType.IsValueType == true) 
                        openApiParameter.Schema.Nullable = true;