44using System ;
55using System . Text . Json ;
66using System . Text . Json . Nodes ;
7+ using Microsoft . OpenApi . Any ;
78using Microsoft . OpenApi . Models ;
89
910namespace Microsoft . OpenApi . Validations . Rules
@@ -41,28 +42,28 @@ public static bool IsEmailAddress(this string input)
4142 }
4243
4344 public static void ValidateDataTypeMismatch (
44- IValidationContext context ,
45- string ruleName ,
46- JsonNode value ,
47- OpenApiSchema schema )
45+ IValidationContext context ,
46+ string ruleName ,
47+ JsonNode value ,
48+ OpenApiSchema schema )
4849 {
4950 if ( schema == null )
5051 {
5152 return ;
5253 }
5354
54- var type = schema . Type . ToString ( ) ;
55+ // convert value to JsonElement and access the ValueKind property to determine the type.
56+ var jsonElement = JsonDocument . Parse ( JsonSerializer . Serialize ( value ) ) . RootElement ;
57+
58+ var type = ( string ) schema . Type ;
5559 var format = schema . Format ;
5660 var nullable = schema . Nullable ;
5761
58- // convert JsonNode to JsonElement
59- JsonElement element = value . GetValue < JsonElement > ( ) ;
60-
6162 // Before checking the type, check first if the schema allows null.
6263 // If so and the data given is also null, this is allowed for any type.
6364 if ( nullable )
6465 {
65- if ( element . ValueKind is JsonValueKind . Null )
66+ if ( jsonElement . ValueKind is JsonValueKind . Null )
6667 {
6768 return ;
6869 }
@@ -73,26 +74,23 @@ public static void ValidateDataTypeMismatch(
7374 // It is not against the spec to have a string representing an object value.
7475 // To represent examples of media types that cannot naturally be represented in JSON or YAML,
7576 // a string value can contain the example with escaping where necessary
76- if ( element . ValueKind is JsonValueKind . String )
77+ if ( jsonElement . ValueKind is JsonValueKind . String )
7778 {
7879 return ;
7980 }
8081
8182 // If value is not a string and also not an object, there is a data mismatch.
82- if ( element . ValueKind is not JsonValueKind . Object )
83+ if ( value is not JsonObject anyObject )
8384 {
8485 context . CreateWarning (
8586 ruleName ,
8687 DataTypeMismatchedErrorMessage ) ;
8788 return ;
8889 }
8990
90- // Else, cast element to object
91- var anyObject = value . AsObject ( ) ;
92-
9391 foreach ( var kvp in anyObject )
9492 {
95- string key = kvp . Key ;
93+ var key = kvp . Key ;
9694 context . Enter ( key ) ;
9795
9896 if ( schema . Properties != null &&
@@ -116,23 +114,20 @@ public static void ValidateDataTypeMismatch(
116114 // It is not against the spec to have a string representing an array value.
117115 // To represent examples of media types that cannot naturally be represented in JSON or YAML,
118116 // a string value can contain the example with escaping where necessary
119- if ( element . ValueKind is JsonValueKind . String )
117+ if ( jsonElement . ValueKind is JsonValueKind . String )
120118 {
121119 return ;
122120 }
123121
124122 // If value is not a string and also not an array, there is a data mismatch.
125- if ( element . ValueKind is not JsonValueKind . Array )
123+ if ( value is not JsonArray anyArray )
126124 {
127125 context . CreateWarning (
128126 ruleName ,
129127 DataTypeMismatchedErrorMessage ) ;
130128 return ;
131129 }
132130
133- // Else, cast element to array
134- var anyArray = value . AsArray ( ) ;
135-
136131 for ( var i = 0 ; i < anyArray . Count ; i ++ )
137132 {
138133 context . Enter ( i . ToString ( ) ) ;
@@ -147,7 +142,7 @@ public static void ValidateDataTypeMismatch(
147142
148143 if ( type == "integer" && format == "int32" )
149144 {
150- if ( element . ValueKind is not JsonValueKind . Number )
145+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
151146 {
152147 context . CreateWarning (
153148 ruleName ,
@@ -159,7 +154,7 @@ public static void ValidateDataTypeMismatch(
159154
160155 if ( type == "integer" && format == "int64" )
161156 {
162- if ( element . ValueKind is not JsonValueKind . Number )
157+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
163158 {
164159 context . CreateWarning (
165160 ruleName ,
@@ -169,16 +164,21 @@ public static void ValidateDataTypeMismatch(
169164 return ;
170165 }
171166
172- if ( type == "integer" && element . ValueKind is not JsonValueKind . Number )
167+ if ( type == "integer" && jsonElement . ValueKind is not JsonValueKind . Number )
173168 {
174- context . CreateWarning (
175- ruleName ,
176- DataTypeMismatchedErrorMessage ) ;
169+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
170+ {
171+ context . CreateWarning (
172+ ruleName ,
173+ DataTypeMismatchedErrorMessage ) ;
174+ }
175+
176+ return ;
177177 }
178178
179179 if ( type == "number" && format == "float" )
180180 {
181- if ( element . ValueKind is not JsonValueKind . Number )
181+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
182182 {
183183 context . CreateWarning (
184184 ruleName ,
@@ -190,7 +190,7 @@ public static void ValidateDataTypeMismatch(
190190
191191 if ( type == "number" && format == "double" )
192192 {
193- if ( element . ValueKind is not JsonValueKind . Number )
193+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
194194 {
195195 context . CreateWarning (
196196 ruleName ,
@@ -202,7 +202,7 @@ public static void ValidateDataTypeMismatch(
202202
203203 if ( type == "number" )
204204 {
205- if ( element . ValueKind is not JsonValueKind . Number )
205+ if ( jsonElement . ValueKind is not JsonValueKind . Number )
206206 {
207207 context . CreateWarning (
208208 ruleName ,
@@ -214,7 +214,7 @@ public static void ValidateDataTypeMismatch(
214214
215215 if ( type == "string" && format == "byte" )
216216 {
217- if ( element . ValueKind is not JsonValueKind . String )
217+ if ( jsonElement . ValueKind is not JsonValueKind . String )
218218 {
219219 context . CreateWarning (
220220 ruleName ,
@@ -226,7 +226,7 @@ public static void ValidateDataTypeMismatch(
226226
227227 if ( type == "string" && format == "date" )
228228 {
229- if ( element . ValueKind is not JsonValueKind . String )
229+ if ( jsonElement . ValueKind is not JsonValueKind . String )
230230 {
231231 context . CreateWarning (
232232 ruleName ,
@@ -238,7 +238,7 @@ public static void ValidateDataTypeMismatch(
238238
239239 if ( type == "string" && format == "date-time" )
240240 {
241- if ( element . ValueKind is not JsonValueKind . String )
241+ if ( jsonElement . ValueKind is not JsonValueKind . String )
242242 {
243243 context . CreateWarning (
244244 ruleName ,
@@ -250,7 +250,7 @@ public static void ValidateDataTypeMismatch(
250250
251251 if ( type == "string" && format == "password" )
252252 {
253- if ( element . ValueKind is not JsonValueKind . String )
253+ if ( jsonElement . ValueKind is not JsonValueKind . String )
254254 {
255255 context . CreateWarning (
256256 ruleName ,
@@ -262,7 +262,7 @@ public static void ValidateDataTypeMismatch(
262262
263263 if ( type == "string" )
264264 {
265- if ( element . ValueKind is not JsonValueKind . String )
265+ if ( jsonElement . ValueKind is not JsonValueKind . String )
266266 {
267267 context . CreateWarning (
268268 ruleName ,
@@ -274,7 +274,7 @@ public static void ValidateDataTypeMismatch(
274274
275275 if ( type == "boolean" )
276276 {
277- if ( element . ValueKind is not JsonValueKind . True || element . ValueKind is not JsonValueKind . True )
277+ if ( jsonElement . ValueKind is not JsonValueKind . True && jsonElement . ValueKind is not JsonValueKind . False )
278278 {
279279 context . CreateWarning (
280280 ruleName ,
0 commit comments