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

NullValueHandling Annotations Generated For Non-Nullable Types #3763

Open uyaem opened 2 years ago

uyaem commented 2 years ago

I have the following (simplified) OpenAPI yaml specification (definition of MyParent for brevity, but wanted to highlight that this is a polymorphic definition in case it is a factor)

MySub:
  allOf:
    - $ref: '#/components/schemas/MyParent'
    - type: object
      properties:
        relativePath:
          type: string
          minLength: 1
        timeout:
          $ref: '#/components/schemas/MyTimeout'
      required:
        - relativePath

MyTimeout:
  type: integer
  format: int32
  minimum: 1
  maximum: 1440

The generated C# class for MySub contains the following property:

[Newtonsoft.Json.JsonProperty(
    "timeout", 
    Required = Newtonsoft.Json.Required.DisallowNull, 
    NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[System.ComponentModel.DataAnnotations.Range(1, 1440)]
public int Timeout { get; set; }

The optional timeout property (as per yaml) is mandatory in the (de-)serialisation process, because the property is generated as int instead of int?.

Is this a bug (maybe due to the property type definition specifying a range)?

RicoSuter commented 2 years ago

It is optional but not nullable (optional and nullable are not the same in JSON).

uyaem commented 2 years ago

Maybe I am misunderstanding the .yaml definition here.

My understanding: Because timeout is not listed in the required section, it can be missing entirely - no issues when serialising. But because the property in the generated class is int and not int?, my de-serialised JSON will always contain { "timeout": 0 } unless I set a value (which is what I don't want).

So where is the issue: The .yaml definition, the generated classes, or my understanding?