@@ -44,11 +44,63 @@ public class OpenApiSchema : IOpenApiReferenceable, IOpenApiExtensible, IOpenApi
4444 /// <inheritdoc />
4545 public IDictionary < string , IOpenApiSchema > Definitions { get ; set ; }
4646
47+ private decimal ? _exclusiveMaximum ;
4748 /// <inheritdoc />
48- public decimal ? V31ExclusiveMaximum { get ; set ; }
49+ public decimal ? ExclusiveMaximum
50+ {
51+ get
52+ {
53+ if ( _exclusiveMaximum . HasValue )
54+ {
55+ return _exclusiveMaximum ;
56+ }
57+ if ( IsExclusiveMaximum == true && _maximum . HasValue )
58+ {
59+ return _maximum ;
60+ }
61+ return null ;
62+ }
63+ set
64+ {
65+ _exclusiveMaximum = value ;
66+ IsExclusiveMaximum = value != null ;
67+ }
68+ }
4969
70+ /// <summary>
71+ /// Compatibility property for OpenAPI 3.0 or earlier serialization of the exclusive maximum value.
72+ /// </summary>
73+ /// DO NOT CHANGE THE VISIBILITY OF THIS PROPERTY TO PUBLIC
74+ internal bool ? IsExclusiveMaximum { get ; set ; }
75+
76+ private decimal ? _exclusiveMinimum ;
5077 /// <inheritdoc />
51- public decimal ? V31ExclusiveMinimum { get ; set ; }
78+ public decimal ? ExclusiveMinimum
79+ {
80+ get
81+ {
82+ if ( _exclusiveMinimum . HasValue )
83+ {
84+ return _exclusiveMinimum ;
85+ }
86+ if ( IsExclusiveMinimum == true && _minimum . HasValue )
87+ {
88+ return _minimum ;
89+ }
90+ return null ;
91+ }
92+ set
93+ {
94+ _exclusiveMinimum = value ;
95+ IsExclusiveMinimum = value != null ;
96+ }
97+ }
98+
99+ /// <summary>
100+ /// Compatibility property for OpenAPI 3.0 or earlier serialization of the exclusive minimum value.
101+ /// </summary>
102+ /// DO NOT CHANGE THE VISIBILITY OF THIS PROPERTY TO PUBLIC
103+ internal bool ? IsExclusiveMinimum { get ; set ; }
52104
53105 /// <inheritdoc />
54106 public bool UnEvaluatedProperties { get ; set ; }
@@ -65,17 +117,42 @@ public class OpenApiSchema : IOpenApiReferenceable, IOpenApiExtensible, IOpenApi
65117 /// <inheritdoc />
66118 public string Description { get ; set ; }
67119
120+ private decimal ? _maximum ;
68121 /// <inheritdoc />
69- public decimal ? Maximum { get ; set ; }
70-
71- /// <inheritdoc />
72- public bool ? ExclusiveMaximum { get ; set ; }
122+ public decimal ? Maximum
123+ {
124+ get
125+ {
126+ if ( IsExclusiveMaximum == true )
127+ {
128+ return null ;
129+ }
130+ return _maximum ;
131+ }
132+ set
133+ {
134+ _maximum = value ;
135+ }
136+ }
73137
74- /// <inheritdoc />
75- public decimal ? Minimum { get ; set ; }
138+ private decimal ? _minimum ;
76139
77140 /// <inheritdoc />
78- public bool ? ExclusiveMinimum { get ; set ; }
141+ public decimal ? Minimum
142+ {
143+ get
144+ {
145+ if ( IsExclusiveMinimum == true )
146+ {
147+ return null ;
148+ }
149+ return _minimum ;
150+ }
151+ set
152+ {
153+ _minimum = value ;
154+ }
155+ }
79156
80157 /// <inheritdoc />
81158 public int ? MaxLength { get ; set ; }
@@ -201,15 +278,18 @@ internal OpenApiSchema(IOpenApiSchema schema)
201278 DynamicRef = schema . DynamicRef ?? DynamicRef ;
202279 Definitions = schema . Definitions != null ? new Dictionary < string , IOpenApiSchema > ( schema . Definitions ) : null ;
203280 UnevaluatedProperties = schema . UnevaluatedProperties ;
204- V31ExclusiveMaximum = schema . V31ExclusiveMaximum ?? V31ExclusiveMaximum ;
205- V31ExclusiveMinimum = schema . V31ExclusiveMinimum ?? V31ExclusiveMinimum ;
281+ ExclusiveMaximum = schema . ExclusiveMaximum ?? ExclusiveMaximum ;
282+ ExclusiveMinimum = schema . ExclusiveMinimum ?? ExclusiveMinimum ;
283+ if ( schema is OpenApiSchema eMSchema )
284+ {
285+ IsExclusiveMaximum = eMSchema . IsExclusiveMaximum ;
286+ IsExclusiveMinimum = eMSchema . IsExclusiveMinimum ;
287+ }
206288 Type = schema . Type ?? Type ;
207289 Format = schema . Format ?? Format ;
208290 Description = schema . Description ?? Description ;
209291 Maximum = schema . Maximum ?? Maximum ;
210- ExclusiveMaximum = schema . ExclusiveMaximum ?? ExclusiveMaximum ;
211292 Minimum = schema . Minimum ?? Minimum ;
212- ExclusiveMinimum = schema . ExclusiveMinimum ?? ExclusiveMinimum ;
213293 MaxLength = schema . MaxLength ?? MaxLength ;
214294 MinLength = schema . MinLength ?? MinLength ;
215295 Pattern = schema . Pattern ?? Pattern ;
@@ -257,6 +337,44 @@ public void SerializeAsV3(IOpenApiWriter writer)
257337 SerializeInternal ( writer , OpenApiSpecVersion . OpenApi3_0 , ( writer , element ) => element . SerializeAsV3 ( writer ) ) ;
258338 }
259339
340+ private static void SerializeBounds ( IOpenApiWriter writer , OpenApiSpecVersion version , string propertyName , string exclusivePropertyName , string isExclusivePropertyName , decimal ? value , decimal ? exclusiveValue , bool ? isExclusiveValue )
341+ {
342+ if ( version >= OpenApiSpecVersion . OpenApi3_1 )
343+ {
344+ if ( exclusiveValue . HasValue )
345+ {
346+ // was explicitly set in the document or object model
347+ writer . WriteProperty ( exclusivePropertyName , exclusiveValue . Value ) ;
348+ }
349+ else if ( isExclusiveValue == true && value . HasValue )
350+ {
351+ // came from parsing an old document
352+ writer . WriteProperty ( exclusivePropertyName , value ) ;
353+ }
354+ else if ( value . HasValue )
355+ {
356+ // was explicitly set in the document or object model
357+ writer . WriteProperty ( propertyName , value ) ;
358+ }
359+ }
360+ else
361+ {
362+ if ( exclusiveValue . HasValue )
363+ {
364+ // was explicitly set in a new document being downcast or object model
365+ writer . WriteProperty ( propertyName , exclusiveValue . Value ) ;
366+ writer . WriteProperty ( isExclusivePropertyName , true ) ;
367+ }
368+ else if ( value . HasValue )
369+ {
370+ // came from parsing an old document, we're just mirroring the information
371+ writer . WriteProperty ( propertyName , value ) ;
372+ if ( isExclusiveValue . HasValue )
373+ writer . WriteProperty ( isExclusivePropertyName , isExclusiveValue . Value ) ;
374+ }
375+ }
376+ }
377+
260378 private void SerializeInternal ( IOpenApiWriter writer , OpenApiSpecVersion version ,
261379 Action < IOpenApiWriter , IOpenApiSerializable > callback )
262380 {
@@ -274,16 +392,12 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
274392 writer . WriteProperty ( OpenApiConstants . MultipleOf , MultipleOf ) ;
275393
276394 // maximum
277- writer . WriteProperty ( OpenApiConstants . Maximum , Maximum ) ;
278-
279395 // exclusiveMaximum
280- writer . WriteProperty ( OpenApiConstants . ExclusiveMaximum , ExclusiveMaximum ) ;
396+ SerializeBounds ( writer , version , OpenApiConstants . Maximum , OpenApiConstants . ExclusiveMaximum , OpenApiConstants . V31ExclusiveMaximum , Maximum , ExclusiveMaximum , IsExclusiveMaximum ) ;
281397
282398 // minimum
283- writer . WriteProperty ( OpenApiConstants . Minimum , Minimum ) ;
284-
285399 // exclusiveMinimum
286- writer . WriteProperty ( OpenApiConstants . ExclusiveMinimum , ExclusiveMinimum ) ;
400+ SerializeBounds ( writer , version , OpenApiConstants . Minimum , OpenApiConstants . ExclusiveMinimum , OpenApiConstants . V31ExclusiveMinimum , Minimum , ExclusiveMinimum , IsExclusiveMinimum ) ;
287401
288402 // maxLength
289403 writer . WriteProperty ( OpenApiConstants . MaxLength , MaxLength ) ;
@@ -407,8 +521,6 @@ internal void WriteJsonSchemaKeywords(IOpenApiWriter writer)
407521 writer . WriteOptionalMap ( OpenApiConstants . Defs , Definitions , ( w , s ) => s . SerializeAsV31 ( w ) ) ;
408522 writer . WriteProperty ( OpenApiConstants . DynamicRef , DynamicRef ) ;
409523 writer . WriteProperty ( OpenApiConstants . DynamicAnchor , DynamicAnchor ) ;
410- writer . WriteProperty ( OpenApiConstants . V31ExclusiveMaximum , V31ExclusiveMaximum ) ;
411- writer . WriteProperty ( OpenApiConstants . V31ExclusiveMinimum , V31ExclusiveMinimum ) ;
412524 writer . WriteProperty ( OpenApiConstants . UnevaluatedProperties , UnevaluatedProperties , false ) ;
413525 writer . WriteOptionalCollection ( OpenApiConstants . Examples , Examples , ( nodeWriter , s ) => nodeWriter . WriteAny ( s ) ) ;
414526 writer . WriteOptionalMap ( OpenApiConstants . PatternProperties , PatternProperties , ( w , s ) => s . SerializeAsV31 ( w ) ) ;
@@ -438,16 +550,12 @@ internal void WriteAsItemsProperties(IOpenApiWriter writer)
438550 writer . WriteOptionalObject ( OpenApiConstants . Default , Default , ( w , d ) => w . WriteAny ( d ) ) ;
439551
440552 // maximum
441- writer . WriteProperty ( OpenApiConstants . Maximum , Maximum ) ;
442-
443553 // exclusiveMaximum
444- writer . WriteProperty ( OpenApiConstants . ExclusiveMaximum , ExclusiveMaximum ) ;
554+ SerializeBounds ( writer , OpenApiSpecVersion . OpenApi2_0 , OpenApiConstants . Maximum , OpenApiConstants . ExclusiveMaximum , OpenApiConstants . V31ExclusiveMaximum , Maximum , ExclusiveMaximum , IsExclusiveMaximum ) ;
445555
446556 // minimum
447- writer . WriteProperty ( OpenApiConstants . Minimum , Minimum ) ;
448-
449557 // exclusiveMinimum
450- writer . WriteProperty ( OpenApiConstants . ExclusiveMinimum , ExclusiveMinimum ) ;
558+ SerializeBounds ( writer , OpenApiSpecVersion . OpenApi2_0 , OpenApiConstants . Minimum , OpenApiConstants . ExclusiveMinimum , OpenApiConstants . V31ExclusiveMinimum , Minimum , ExclusiveMinimum , IsExclusiveMinimum ) ;
451559
452560 // maxLength
453561 writer . WriteProperty ( OpenApiConstants . MaxLength , MaxLength ) ;
@@ -522,16 +630,12 @@ private void SerializeAsV2(
522630 writer . WriteProperty ( OpenApiConstants . MultipleOf , MultipleOf ) ;
523631
524632 // maximum
525- writer . WriteProperty ( OpenApiConstants . Maximum , Maximum ) ;
526-
527633 // exclusiveMaximum
528- writer . WriteProperty ( OpenApiConstants . ExclusiveMaximum , ExclusiveMaximum ) ;
634+ SerializeBounds ( writer , OpenApiSpecVersion . OpenApi2_0 , OpenApiConstants . Maximum , OpenApiConstants . ExclusiveMaximum , OpenApiConstants . V31ExclusiveMaximum , Maximum , ExclusiveMaximum , IsExclusiveMaximum ) ;
529635
530636 // minimum
531- writer . WriteProperty ( OpenApiConstants . Minimum , Minimum ) ;
532-
533637 // exclusiveMinimum
534- writer . WriteProperty ( OpenApiConstants . ExclusiveMinimum , ExclusiveMinimum ) ;
638+ SerializeBounds ( writer , OpenApiSpecVersion . OpenApi2_0 , OpenApiConstants . Minimum , OpenApiConstants . ExclusiveMinimum , OpenApiConstants . V31ExclusiveMinimum , Minimum , ExclusiveMinimum , IsExclusiveMinimum ) ;
535639
536640 // maxLength
537641 writer . WriteProperty ( OpenApiConstants . MaxLength , MaxLength ) ;
0 commit comments