[BUG][C#] Should use nullable types for non-required properties
See original GitHub issueBug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- What’s the version of OpenAPI Generator used?
- Have you search for related issues/PRs?
- What’s the actual output vs expected output?
- [Optional] Bounty to sponsor the fix (example)
Description
The C# generators currently generate model classes using non-nullable types for properties which are not required, which can’t represent instances where those properties are not present.
openapi-generator version
v4.0.0 and later
OpenAPI declaration file content or url
Example OpenAPI 3.0.2 document
openapi: '3.0.2'
info:
title: non-required property example
version: '1.0.0'
components:
schemas:
DateRange:
description: A possibly open-ended date range.
type: object
properties:
start:
type: string
format: date-time
end:
type: string
format: date-time
required:
- start
paths:
/date-ranges:
get:
operationId: getDateRanges
responses:
default:
description: Get date ranges
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DateRange'
post:
operationId: addDateRange
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DateRange'
responses:
'201':
description: Success
Note that end
is not declared nullable: true
because end
is never null
in the JSON produced or consumed by the API. It is either a date string, or not present.
Command line used for generation
java -jar openapi-generator-cli.jar generate -g csharp-netcore -i openapi.yaml -o generated
Steps to reproduce
- Ensure the API returns at least one open-ended range (i.e. a
DateRange
object without anend
property). - Call
GetDateRanges
and note thatEnd
for the open-ended range isDateTime(1900-01-01)
, which is problematic since it is indistinguishable from"end":"1900-01-01"
and likely violates the constraint thatEnd
is not beforeStart
. - Note that there is no way to call
AddDateRange
with an open-ended range, sinceEnd
will always have a value.
Related issues/PRs
The regression occurred between v3.0.2 and v4.0.0. Bisect says the first bad commit is 3744273312 (v4.0.0
), so I’m obviously doing something wrong. (Maybe cli
is using published core
of same version, rather than locally-built version?) Advice on how to bisect would be appreciated.
The issue was also discussed in https://github.com/OpenAPITools/openapi-generator/issues/3725#issuecomment-545039145.
Suggest a fix
I believe nullable types should be used for properties which are either nullable
or not required
, since null
in C# is a reasonable representation of both JSON properties which are null
and properties which are not present.
Thanks for considering, Kevin
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:11 (3 by maintainers)
Yes, but for Swagger 2.0 it’s a vendor extension. From the upgrade note:
This to me, does not seem right.
Also, an optional parameter without a default value must be nullable. Nothing else makes sense. The API spec for such a field says “this does not have to have value” which is exactly the same meaning as “this is nullable”. Anything else is overriding the spec to effectively make the field required.
I see the
nullable
as specifying that a field can be null _even though it has a default value. Otherwise you end up with a catch-22: A field which is not required, has no default value but is not nullable - what is that? In practice, you have to give a value (since null will fail) so you’re violating the API spec and making the field required. Or am I missing something - what value can be given to such a field?At a bear minimum there should be a generation-time flag to make it behave like this.
As I see it, for v2 we are requiring a vendor extension and even for v3 we are requiring that the spec is written in a specific way to get around the generator implementation.
@wing328 I’ve found your following statement in the PR that probably introduced this regression:
Does that mean that openapi-generator will always require
x:nullable:true
from now on? Or could this issue be fixed?