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 ; 
@@ -356,12 +358,6 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
356358            // default 
357359            writer . WriteOptionalObject ( OpenApiConstants . Default ,  Default ,  ( w ,  d )  =>  w . WriteAny ( d ) ) ; 
358360
359-             // nullable 
360-             if  ( version  is  OpenApiSpecVersion . OpenApi3_0 ) 
361-             { 
362-                 writer . WriteProperty ( OpenApiConstants . Nullable ,  Nullable ,  false ) ; 
363-             } 
364- 
365361            // discriminator 
366362            writer . WriteOptionalObject ( OpenApiConstants . Discriminator ,  Discriminator ,  callback ) ; 
367363
@@ -636,20 +632,39 @@ private void SerializeAsV2(
636632
637633        private  void  SerializeTypeProperty ( JsonSchemaType ?  type ,  IOpenApiWriter  writer ,  OpenApiSpecVersion  version ) 
638634        { 
635+             // check whether nullable is true for upcasting purposes 
636+             var  isNullable  =  Nullable  || 
637+                             ( Type . HasValue  &&  Type . Value . HasFlag ( JsonSchemaType . Null ) )   || 
638+                                 Extensions  is  not null  && 
639+                                 Extensions . TryGetValue ( OpenApiConstants . NullableExtension ,  out  var  nullExtRawValue )  &&  
640+                                 nullExtRawValue  is  OpenApiAny  {  Node :  JsonNode  jsonNode }  && 
641+                                 jsonNode . GetValueKind ( )  is  JsonValueKind . True ; 
639642            if  ( type  is  null ) 
640643            { 
641-                 return ; 
642-             } 
643-             if  ( ! HasMultipleTypes ( type . Value ) ) 
644-             { 
645-                 // check whether nullable is true for upcasting purposes 
646-                 if  ( version  is  OpenApiSpecVersion . OpenApi3_1  &&  ( Nullable  ||  Extensions . ContainsKey ( OpenApiConstants . NullableExtension ) ) ) 
644+                 if  ( version  is  OpenApiSpecVersion . OpenApi3_0  &&  isNullable ) 
647645                { 
648-                     UpCastSchemaTypeToV31 ( type ,   writer ) ; 
646+                     writer . WriteProperty ( OpenApiConstants . Nullable ,   true ) ; 
649647                } 
650-                 else 
648+             } 
649+             else  if  ( ! HasMultipleTypes ( type . Value ) ) 
650+             { 
651+                 
652+                 switch  ( version ) 
651653                { 
652-                     writer . WriteProperty ( OpenApiConstants . Type ,  type . Value . ToIdentifier ( ) ) ; 
654+                     case  OpenApiSpecVersion . OpenApi3_1  when  isNullable : 
655+                         UpCastSchemaTypeToV31 ( type . Value ,  writer ) ; 
656+                         break ; 
657+                     case  OpenApiSpecVersion . OpenApi3_0  when  isNullable  &&  type . Value  ==  JsonSchemaType . Null : 
658+                         writer . WriteProperty ( OpenApiConstants . Nullable ,  true ) ; 
659+                         writer . WriteProperty ( OpenApiConstants . Type ,  JsonSchemaType . Object . ToIdentifier ( ) ) ; 
660+                         break ; 
661+                     case  OpenApiSpecVersion . OpenApi3_0  when  isNullable  &&  type . Value  !=  JsonSchemaType . Null : 
662+                         writer . WriteProperty ( OpenApiConstants . Nullable ,  true ) ; 
663+                         writer . WriteProperty ( OpenApiConstants . Type ,  type . Value . ToIdentifier ( ) ) ; 
664+                         break ; 
665+                     default : 
666+                         writer . WriteProperty ( OpenApiConstants . Type ,  type . Value . ToIdentifier ( ) ) ; 
667+                         break ; 
653668                } 
654669            } 
655670            else 
@@ -664,6 +679,10 @@ private void SerializeTypeProperty(JsonSchemaType? type, IOpenApiWriter writer,
664679                    var  list  =  ( from  JsonSchemaType  flag  in  jsonSchemaTypeValues 
665680                                where  type . Value . HasFlag ( flag ) 
666681                                select  flag ) . ToList ( ) ; 
682+                     if  ( Nullable  &&  ! list . Contains ( JsonSchemaType . Null ) ) 
683+                     { 
684+                         list . Add ( JsonSchemaType . Null ) ; 
685+                     } 
667686                    writer . WriteOptionalCollection ( OpenApiConstants . Type ,  list ,  ( w ,  s )  =>  w . WriteValue ( s . ToIdentifier ( ) ) ) ; 
668687                } 
669688            }  
@@ -681,14 +700,21 @@ private static bool HasMultipleTypes(JsonSchemaType schemaType)
681700                    schemaTypeNumeric  !=  ( int ) JsonSchemaType . Null ; 
682701        } 
683702
684-         private  void  UpCastSchemaTypeToV31 ( JsonSchemaType ?  type ,  IOpenApiWriter  writer ) 
703+         private  static   void  UpCastSchemaTypeToV31 ( JsonSchemaType  type ,  IOpenApiWriter  writer ) 
685704        { 
686705            // create a new array and insert the type and "null" as values 
687-             Type  =  type  |  JsonSchemaType . Null ; 
688-             var  list  =  ( from  JsonSchemaType ?  flag  in  jsonSchemaTypeValues // Check if the flag is set in 'type' using a bitwise AND operation 
689-                         where  Type . Value . HasFlag ( flag ) 
706+             var   temporaryType  =  type  |  JsonSchemaType . Null ; 
707+             var  list  =  ( from  JsonSchemaType  flag  in  jsonSchemaTypeValues // Check if the flag is set in 'type' using a bitwise AND operation 
708+                         where  temporaryType . HasFlag ( flag ) 
690709                        select  flag . ToIdentifier ( ) ) . ToList ( ) ; 
691-             writer . WriteOptionalCollection ( OpenApiConstants . Type ,  list ,  ( w ,  s )  =>  w . WriteValue ( s ) ) ; 
710+             if  ( list . Count  >  1 ) 
711+             { 
712+                 writer . WriteOptionalCollection ( OpenApiConstants . Type ,  list ,  ( w ,  s )  =>  w . WriteValue ( s ) ) ; 
713+             } 
714+             else 
715+             { 
716+                 writer . WriteProperty ( OpenApiConstants . Type ,  list [ 0 ] ) ; 
717+             } 
692718        } 
693719
694720#if NET5_0_OR_GREATER 
@@ -711,7 +737,7 @@ private void DowncastTypeArrayToV2OrV3(JsonSchemaType schemaType, IOpenApiWriter
711737
712738            if  ( ! HasMultipleTypes ( schemaType  ^  JsonSchemaType . Null )  &&  ( schemaType  &  JsonSchemaType . Null )  ==  JsonSchemaType . Null )  // checks for two values and one is null 
713739            { 
714-                 foreach  ( JsonSchemaType ?  flag  in  jsonSchemaTypeValues ) 
740+                 foreach  ( JsonSchemaType  flag  in  jsonSchemaTypeValues ) 
715741                { 
716742                    // Skip if the flag is not set or if it's the Null flag 
717743                    if  ( schemaType . HasFlag ( flag )  &&  flag  !=  JsonSchemaType . Null ) 
0 commit comments