44using System ;
55using System . Collections . Generic ;
66using System . Linq ;
7+ using System . Text . Json ;
78using System . Text . Json . Nodes ;
9+ using Microsoft . OpenApi . Any ;
810using Microsoft . OpenApi . Extensions ;
911using Microsoft . OpenApi . Helpers ;
1012using Microsoft . OpenApi . Interfaces ;
@@ -355,12 +357,6 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
355357 // default
356358 writer . WriteOptionalObject ( OpenApiConstants . Default , Default , ( w , d ) => w . WriteAny ( d ) ) ;
357359
358- // nullable
359- if ( version is OpenApiSpecVersion . OpenApi3_0 )
360- {
361- writer . WriteProperty ( OpenApiConstants . Nullable , Nullable , false ) ;
362- }
363-
364360 // discriminator
365361 writer . WriteOptionalObject ( OpenApiConstants . Discriminator , Discriminator , callback ) ;
366362
@@ -635,20 +631,33 @@ private void SerializeAsV2(
635631
636632 private void SerializeTypeProperty ( JsonSchemaType ? type , IOpenApiWriter writer , OpenApiSpecVersion version )
637633 {
634+ // check whether nullable is true for upcasting purposes
635+ var isNullable = Nullable ||
636+ Extensions . TryGetValue ( OpenApiConstants . NullableExtension , out var nullExtRawValue ) &&
637+ nullExtRawValue is OpenApiAny openApiAny &&
638+ openApiAny . Node is JsonNode jsonNode &&
639+ jsonNode . GetValueKind ( ) is JsonValueKind . True ;
638640 if ( type is null )
639641 {
640- return ;
641- }
642- if ( ! HasMultipleTypes ( type . Value ) )
643- {
644- // check whether nullable is true for upcasting purposes
645- if ( version is OpenApiSpecVersion . OpenApi3_1 && ( Nullable || Extensions . ContainsKey ( OpenApiConstants . NullableExtension ) ) )
642+ if ( version is OpenApiSpecVersion . OpenApi3_0 && isNullable )
646643 {
647- UpCastSchemaTypeToV31 ( type , writer ) ;
644+ writer . WriteProperty ( OpenApiConstants . Nullable , true ) ;
648645 }
649- else
646+ }
647+ else if ( ! HasMultipleTypes ( type . Value ) )
648+ {
649+
650+ switch ( version )
650651 {
651- writer . WriteProperty ( OpenApiConstants . Type , type . Value . ToIdentifier ( ) ) ;
652+ case OpenApiSpecVersion . OpenApi3_1 when isNullable :
653+ UpCastSchemaTypeToV31 ( type . Value , writer ) ;
654+ break ;
655+ case OpenApiSpecVersion . OpenApi3_0 when isNullable :
656+ writer . WriteProperty ( OpenApiConstants . Nullable , true ) ;
657+ goto default ;
658+ default :
659+ writer . WriteProperty ( OpenApiConstants . Type , type . Value . ToIdentifier ( ) ) ;
660+ break ;
652661 }
653662 }
654663 else
@@ -663,6 +672,10 @@ private void SerializeTypeProperty(JsonSchemaType? type, IOpenApiWriter writer,
663672 var list = ( from JsonSchemaType flag in jsonSchemaTypeValues
664673 where type . Value . HasFlag ( flag )
665674 select flag ) . ToList ( ) ;
675+ if ( Nullable && ! list . Contains ( JsonSchemaType . Null ) )
676+ {
677+ list . Add ( JsonSchemaType . Null ) ;
678+ }
666679 writer . WriteOptionalCollection ( OpenApiConstants . Type , list , ( w , s ) => w . WriteValue ( s . ToIdentifier ( ) ) ) ;
667680 }
668681 }
@@ -680,12 +693,12 @@ private static bool HasMultipleTypes(JsonSchemaType schemaType)
680693 schemaTypeNumeric != ( int ) JsonSchemaType . Null ;
681694 }
682695
683- private void UpCastSchemaTypeToV31 ( JsonSchemaType ? type , IOpenApiWriter writer )
696+ private void UpCastSchemaTypeToV31 ( JsonSchemaType type , IOpenApiWriter writer )
684697 {
685698 // create a new array and insert the type and "null" as values
686- Type = type | JsonSchemaType . Null ;
699+ var temporaryType = type | JsonSchemaType . Null ;
687700 var list = ( from JsonSchemaType ? flag in jsonSchemaTypeValues // Check if the flag is set in 'type' using a bitwise AND operation
688- where Type . Value . HasFlag ( flag )
701+ where temporaryType . HasFlag ( flag )
689702 select flag . ToIdentifier ( ) ) . ToList ( ) ;
690703 writer . WriteOptionalCollection ( OpenApiConstants . Type , list , ( w , s ) => w . WriteValue ( s ) ) ;
691704 }
0 commit comments