diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 03df232..79512eb 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"csharpier": {
- "version": "1.2.1",
+ "version": "1.2.4",
"commands": [
"csharpier"
],
diff --git a/.csharpierignore b/.csharpierignore
index 341ae1b..5bd2c71 100644
--- a/.csharpierignore
+++ b/.csharpierignore
@@ -1 +1,5 @@
.nuget
+.idea
+*.slnx
+*.csproj
+*.props
\ No newline at end of file
diff --git a/.idea/.idea.OpenApiValidate/.idea/copilot.data.migration.ask2agent.xml b/.idea/.idea.OpenApiValidate/.idea/copilot.data.migration.ask2agent.xml
new file mode 100644
index 0000000..1f2ea11
--- /dev/null
+++ b/.idea/.idea.OpenApiValidate/.idea/copilot.data.migration.ask2agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 1224431..10060ca 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -4,9 +4,9 @@
true
-
+
-
+
all
diff --git a/src/OpenApiValidate/Helpers/OpenApiExtensions.cs b/src/OpenApiValidate/Helpers/OpenApiExtensions.cs
index d7ce52e..68058d3 100644
--- a/src/OpenApiValidate/Helpers/OpenApiExtensions.cs
+++ b/src/OpenApiValidate/Helpers/OpenApiExtensions.cs
@@ -5,18 +5,26 @@ namespace OpenApiValidate;
internal static class OpenApiExtensions
{
+ private static readonly OpenApiWriterSettings OpenApiWriterSettings = new()
+ {
+ InlineExternalReferences = true,
+ InlineLocalReferences = true,
+ };
+
+ private static readonly BuildOptions JsonSchemaBuildOptions = new()
+ {
+ Dialect = Json.Schema.OpenApi.Dialect.OpenApi_31,
+ };
+
public static JsonSchema ToJsonSchema(this IOpenApiSchema schema)
{
var writer = new StringWriter();
- var writerSettings = new OpenApiWriterSettings
- {
- InlineExternalReferences = true,
- InlineLocalReferences = true,
- };
- schema.SerializeAsV31(new OpenApiJsonWriter(writer, writerSettings));
+
+ schema.SerializeAsV31(new OpenApiJsonWriter(writer, OpenApiWriterSettings));
var json = writer.ToString();
- return JsonSchema.FromText(json);
+
+ return JsonSchema.FromText(json, JsonSchemaBuildOptions);
}
public static bool TryMatchResponse(
@@ -84,7 +92,7 @@ private static bool IsPathMatch(PathString specPath, PathString requestPath)
{
var segment = specPath.Segments[i];
- if (segment.StartsWith("{") && segment.EndsWith("}"))
+ if (segment.StartsWith('{') && segment.EndsWith('}'))
{
// Is template parameter, so skip checking
continue;
diff --git a/src/OpenApiValidate/OpenApiValidate.csproj b/src/OpenApiValidate/OpenApiValidate.csproj
index db5acb8..ecd1142 100644
--- a/src/OpenApiValidate/OpenApiValidate.csproj
+++ b/src/OpenApiValidate/OpenApiValidate.csproj
@@ -5,7 +5,7 @@
enable
-
+
diff --git a/src/OpenApiValidate/OpenApiValidator.cs b/src/OpenApiValidate/OpenApiValidator.cs
index 9b05854..4656590 100644
--- a/src/OpenApiValidate/OpenApiValidator.cs
+++ b/src/OpenApiValidate/OpenApiValidator.cs
@@ -1,4 +1,5 @@
using System.Text;
+using System.Text.Json;
using System.Text.Json.Nodes;
using System.Web;
using Json.Schema;
@@ -320,15 +321,20 @@ out List validationErrors
var jsonSchema = schema.ToJsonSchema();
var validationResult = jsonSchema.Evaluate(
- JsonNode.Parse(body),
+ JsonDocument.Parse(body).RootElement,
JsonSchemaEvaluationOptions
);
- if (!validationResult.IsValid)
+ if (validationResult.IsValid)
{
- var message = new StringBuilder();
+ return true;
+ }
+
+ var message = new StringBuilder();
- foreach (var detail in validationResult.Details.Where(d => d.HasErrors))
+ if (validationResult.Details != null)
+ {
+ foreach (var detail in validationResult.Details.Where(d => d.Errors != null))
{
var path = detail.EvaluationPath.ToString();
@@ -337,15 +343,13 @@ out List validationErrors
message.AppendLine($"[{error.Key}] {path}: {error.Value}");
}
}
-
- validationErrors.Add(
- new ValidationError($"{bodyType} body failed schema validation: \n\n" + message)
- );
-
- return false;
}
- return true;
+ validationErrors.Add(
+ new ValidationError($"{bodyType} body failed schema validation: \n\n" + message)
+ );
+
+ return false;
}
private OpenApiServer? FindServer(Request request)
diff --git a/src/OpenApiValidate/packages.lock.json b/src/OpenApiValidate/packages.lock.json
index 1e206d3..b26d64a 100644
--- a/src/OpenApiValidate/packages.lock.json
+++ b/src/OpenApiValidate/packages.lock.json
@@ -2,121 +2,121 @@
"version": 2,
"dependencies": {
"net8.0": {
- "JsonSchema.Net": {
+ "JsonSchema.Net.OpenApi": {
"type": "Direct",
- "requested": "[7.4.0, )",
- "resolved": "7.4.0",
- "contentHash": "5T3DWENwuCzLwFWz0qjXXVWA8+5+gC95OLkhqUBWpVpWBMr9gwfhWNeX8rWyr+fLQ7pIQ+lWuHIrmXRudxOOSw==",
+ "requested": "[4.0.0, )",
+ "resolved": "4.0.0",
+ "contentHash": "h7MIvE30KsozuK7JzfTt8gO72o3Qqxgu3ruyw44LmE9wH1FVVcH00keUhjQI+FyoZbO5QTMq2NJJmslQK8ZKcA==",
"dependencies": {
- "JsonPointer.Net": "5.3.1"
+ "JsonSchema.Net": "8.0.0"
}
},
"Microsoft.OpenApi.YamlReader": {
"type": "Direct",
- "requested": "[3.0.1, )",
- "resolved": "3.0.1",
- "contentHash": "zKac6o3McDkjZOm51l8t5DmHX+1HlUZ4xzGjTd0StJMhsOYC0BK1EQaD51IdUQiLWDAsFPD6ES5P1hdTI5uQtg==",
+ "requested": "[3.1.1, )",
+ "resolved": "3.1.1",
+ "contentHash": "KYt4L25yAsLRVb9dhbfXGGcAQZQMbiLcTemDpCIiNaN+7DNygN+boUQXS5ByANyWzndJ5iKCgt2yWkspJXzwEQ==",
"dependencies": {
- "Microsoft.OpenApi": "3.0.1",
- "SharpYaml": "2.1.4",
- "System.Text.Json": "8.0.5"
+ "Microsoft.OpenApi": "3.1.1",
+ "SharpYaml": "2.1.4"
}
},
"Humanizer.Core": {
"type": "Transitive",
- "resolved": "2.14.1",
- "contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
+ "resolved": "3.0.1",
+ "contentHash": "scB3+KcxNmEjZK5V8rKCW2gIiL8m8KH91w14FuuExyhi9xTyAJ+jr+DDxGdy12mHmioe2uvjxTfMgM7WmSUFlw=="
},
"Json.More.Net": {
"type": "Transitive",
- "resolved": "2.1.1",
- "contentHash": "ZXAKl2VsdnIZeUo1PFII3Oi1m1L4YQjEyDjygHfHln5vgsjgIo749X6xWkv7qFYp8RROES+vOEfDcvvoVgs8kA=="
+ "resolved": "2.2.0",
+ "contentHash": "fiyEZJNgiCzDa7/N9bZ+CnM5qnawyJ54+CkHNZ2svwxWBWNNFzydJ7RlroqMdOjokGBiLcKIxdajNvOklzlYqQ=="
},
"JsonPointer.Net": {
"type": "Transitive",
- "resolved": "5.3.1",
- "contentHash": "3e2OJjU0OaE26XC/klgxbJuXvteFWTDJIJv0ITYWcJEoskq7jzUwPSC1s0iz4wPPQnfN7vwwFmg2gJfwRAPwgw==",
+ "resolved": "6.0.0",
+ "contentHash": "OOObaRq33mNkoMFM1JfdW3nD6U6xF0MHHxPFAxSpKHNNTK6Zbt8U9grquJ+m2onZ1M7cruho0fWzHjhpjEXjog==",
"dependencies": {
- "Humanizer.Core": "2.14.1",
- "Json.More.Net": "2.1.1"
+ "Humanizer.Core": "3.0.1",
+ "Json.More.Net": "2.2.0"
}
},
"Microsoft.OpenApi": {
"type": "Transitive",
- "resolved": "3.0.1",
- "contentHash": "bEUxdaMrfX/1T/U0I9GOxi3nmZTlMZd+/rOPWVKnfIMlzV28VPXmLg7OiQvFa1ivOEruLSdZCUSc4KgroZZHpg==",
- "dependencies": {
- "System.Text.Json": "8.0.5"
- }
+ "resolved": "3.1.1",
+ "contentHash": "/NcgAtqQzs6Djm7sJ3DYaFTTUiXOVmJVAljaQ+IQFV5ZiRGheER8OKLlHgke+Yb0CquiqtdgA4DN+98+Uu9G/Q=="
},
"SharpYaml": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "/iwULhVBpTjD4wPZhLU+eUWBanDvri/2AGx5YbaAj5kp9kXzhqUfJEy56H5Yi+c+OXsdm/oKD1aTKB24BFp8cw=="
},
- "System.Text.Json": {
- "type": "Transitive",
- "resolved": "8.0.5",
- "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg=="
+ "JsonSchema.Net": {
+ "type": "CentralTransitive",
+ "requested": "[8.0.5, )",
+ "resolved": "8.0.0",
+ "contentHash": "YQQo7/ozc7kbmTaCE4p1127z3LyHuWLGfXk/7sTqNVVpUawEIop9mtlyMKSOPZshM777oTjaTHc1f1/S/Gxnjw==",
+ "dependencies": {
+ "JsonPointer.Net": "6.0.0"
+ }
}
},
"net9.0": {
- "JsonSchema.Net": {
+ "JsonSchema.Net.OpenApi": {
"type": "Direct",
- "requested": "[7.4.0, )",
- "resolved": "7.4.0",
- "contentHash": "5T3DWENwuCzLwFWz0qjXXVWA8+5+gC95OLkhqUBWpVpWBMr9gwfhWNeX8rWyr+fLQ7pIQ+lWuHIrmXRudxOOSw==",
+ "requested": "[4.0.0, )",
+ "resolved": "4.0.0",
+ "contentHash": "h7MIvE30KsozuK7JzfTt8gO72o3Qqxgu3ruyw44LmE9wH1FVVcH00keUhjQI+FyoZbO5QTMq2NJJmslQK8ZKcA==",
"dependencies": {
- "JsonPointer.Net": "5.3.1"
+ "JsonSchema.Net": "8.0.0"
}
},
"Microsoft.OpenApi.YamlReader": {
"type": "Direct",
- "requested": "[3.0.1, )",
- "resolved": "3.0.1",
- "contentHash": "zKac6o3McDkjZOm51l8t5DmHX+1HlUZ4xzGjTd0StJMhsOYC0BK1EQaD51IdUQiLWDAsFPD6ES5P1hdTI5uQtg==",
+ "requested": "[3.1.1, )",
+ "resolved": "3.1.1",
+ "contentHash": "KYt4L25yAsLRVb9dhbfXGGcAQZQMbiLcTemDpCIiNaN+7DNygN+boUQXS5ByANyWzndJ5iKCgt2yWkspJXzwEQ==",
"dependencies": {
- "Microsoft.OpenApi": "3.0.1",
- "SharpYaml": "2.1.4",
- "System.Text.Json": "8.0.5"
+ "Microsoft.OpenApi": "3.1.1",
+ "SharpYaml": "2.1.4"
}
},
"Humanizer.Core": {
"type": "Transitive",
- "resolved": "2.14.1",
- "contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
+ "resolved": "3.0.1",
+ "contentHash": "scB3+KcxNmEjZK5V8rKCW2gIiL8m8KH91w14FuuExyhi9xTyAJ+jr+DDxGdy12mHmioe2uvjxTfMgM7WmSUFlw=="
},
"Json.More.Net": {
"type": "Transitive",
- "resolved": "2.1.1",
- "contentHash": "ZXAKl2VsdnIZeUo1PFII3Oi1m1L4YQjEyDjygHfHln5vgsjgIo749X6xWkv7qFYp8RROES+vOEfDcvvoVgs8kA=="
+ "resolved": "2.2.0",
+ "contentHash": "fiyEZJNgiCzDa7/N9bZ+CnM5qnawyJ54+CkHNZ2svwxWBWNNFzydJ7RlroqMdOjokGBiLcKIxdajNvOklzlYqQ=="
},
"JsonPointer.Net": {
"type": "Transitive",
- "resolved": "5.3.1",
- "contentHash": "3e2OJjU0OaE26XC/klgxbJuXvteFWTDJIJv0ITYWcJEoskq7jzUwPSC1s0iz4wPPQnfN7vwwFmg2gJfwRAPwgw==",
+ "resolved": "6.0.0",
+ "contentHash": "OOObaRq33mNkoMFM1JfdW3nD6U6xF0MHHxPFAxSpKHNNTK6Zbt8U9grquJ+m2onZ1M7cruho0fWzHjhpjEXjog==",
"dependencies": {
- "Humanizer.Core": "2.14.1",
- "Json.More.Net": "2.1.1"
+ "Humanizer.Core": "3.0.1",
+ "Json.More.Net": "2.2.0"
}
},
"Microsoft.OpenApi": {
"type": "Transitive",
- "resolved": "3.0.1",
- "contentHash": "bEUxdaMrfX/1T/U0I9GOxi3nmZTlMZd+/rOPWVKnfIMlzV28VPXmLg7OiQvFa1ivOEruLSdZCUSc4KgroZZHpg==",
- "dependencies": {
- "System.Text.Json": "8.0.5"
- }
+ "resolved": "3.1.1",
+ "contentHash": "/NcgAtqQzs6Djm7sJ3DYaFTTUiXOVmJVAljaQ+IQFV5ZiRGheER8OKLlHgke+Yb0CquiqtdgA4DN+98+Uu9G/Q=="
},
"SharpYaml": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "/iwULhVBpTjD4wPZhLU+eUWBanDvri/2AGx5YbaAj5kp9kXzhqUfJEy56H5Yi+c+OXsdm/oKD1aTKB24BFp8cw=="
},
- "System.Text.Json": {
- "type": "Transitive",
- "resolved": "8.0.5",
- "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg=="
+ "JsonSchema.Net": {
+ "type": "CentralTransitive",
+ "requested": "[8.0.5, )",
+ "resolved": "8.0.0",
+ "contentHash": "YQQo7/ozc7kbmTaCE4p1127z3LyHuWLGfXk/7sTqNVVpUawEIop9mtlyMKSOPZshM777oTjaTHc1f1/S/Gxnjw==",
+ "dependencies": {
+ "JsonPointer.Net": "6.0.0"
+ }
}
}
}
diff --git a/test/OpenApiValidate.Tests/packages.lock.json b/test/OpenApiValidate.Tests/packages.lock.json
index 543a3ba..75f12d6 100644
--- a/test/OpenApiValidate.Tests/packages.lock.json
+++ b/test/OpenApiValidate.Tests/packages.lock.json
@@ -53,21 +53,21 @@
},
"Humanizer.Core": {
"type": "Transitive",
- "resolved": "2.14.1",
- "contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
+ "resolved": "3.0.1",
+ "contentHash": "scB3+KcxNmEjZK5V8rKCW2gIiL8m8KH91w14FuuExyhi9xTyAJ+jr+DDxGdy12mHmioe2uvjxTfMgM7WmSUFlw=="
},
"Json.More.Net": {
"type": "Transitive",
- "resolved": "2.1.1",
- "contentHash": "ZXAKl2VsdnIZeUo1PFII3Oi1m1L4YQjEyDjygHfHln5vgsjgIo749X6xWkv7qFYp8RROES+vOEfDcvvoVgs8kA=="
+ "resolved": "2.2.0",
+ "contentHash": "fiyEZJNgiCzDa7/N9bZ+CnM5qnawyJ54+CkHNZ2svwxWBWNNFzydJ7RlroqMdOjokGBiLcKIxdajNvOklzlYqQ=="
},
"JsonPointer.Net": {
"type": "Transitive",
- "resolved": "5.3.1",
- "contentHash": "3e2OJjU0OaE26XC/klgxbJuXvteFWTDJIJv0ITYWcJEoskq7jzUwPSC1s0iz4wPPQnfN7vwwFmg2gJfwRAPwgw==",
+ "resolved": "6.0.0",
+ "contentHash": "OOObaRq33mNkoMFM1JfdW3nD6U6xF0MHHxPFAxSpKHNNTK6Zbt8U9grquJ+m2onZ1M7cruho0fWzHjhpjEXjog==",
"dependencies": {
- "Humanizer.Core": "2.14.1",
- "Json.More.Net": "2.1.1"
+ "Humanizer.Core": "3.0.1",
+ "Json.More.Net": "2.2.0"
}
},
"Microsoft.ApplicationInsights": {
@@ -95,8 +95,8 @@
},
"Microsoft.OpenApi": {
"type": "Transitive",
- "resolved": "3.0.1",
- "contentHash": "bEUxdaMrfX/1T/U0I9GOxi3nmZTlMZd+/rOPWVKnfIMlzV28VPXmLg7OiQvFa1ivOEruLSdZCUSc4KgroZZHpg==",
+ "resolved": "3.1.1",
+ "contentHash": "/NcgAtqQzs6Djm7sJ3DYaFTTUiXOVmJVAljaQ+IQFV5ZiRGheER8OKLlHgke+Yb0CquiqtdgA4DN+98+Uu9G/Q==",
"dependencies": {
"System.Text.Json": "8.0.5"
}
@@ -287,26 +287,35 @@
"openapivalidate": {
"type": "Project",
"dependencies": {
- "JsonSchema.Net": "[7.4.0, )",
- "Microsoft.OpenApi.YamlReader": "[3.0.1, )"
+ "JsonSchema.Net.OpenApi": "[4.0.0, )",
+ "Microsoft.OpenApi.YamlReader": "[3.1.1, )"
}
},
"JsonSchema.Net": {
"type": "CentralTransitive",
- "requested": "[7.4.0, )",
- "resolved": "7.4.0",
- "contentHash": "5T3DWENwuCzLwFWz0qjXXVWA8+5+gC95OLkhqUBWpVpWBMr9gwfhWNeX8rWyr+fLQ7pIQ+lWuHIrmXRudxOOSw==",
+ "requested": "[8.0.5, )",
+ "resolved": "8.0.0",
+ "contentHash": "YQQo7/ozc7kbmTaCE4p1127z3LyHuWLGfXk/7sTqNVVpUawEIop9mtlyMKSOPZshM777oTjaTHc1f1/S/Gxnjw==",
"dependencies": {
- "JsonPointer.Net": "5.3.1"
+ "JsonPointer.Net": "6.0.0"
+ }
+ },
+ "JsonSchema.Net.OpenApi": {
+ "type": "CentralTransitive",
+ "requested": "[4.0.0, )",
+ "resolved": "4.0.0",
+ "contentHash": "h7MIvE30KsozuK7JzfTt8gO72o3Qqxgu3ruyw44LmE9wH1FVVcH00keUhjQI+FyoZbO5QTMq2NJJmslQK8ZKcA==",
+ "dependencies": {
+ "JsonSchema.Net": "8.0.0"
}
},
"Microsoft.OpenApi.YamlReader": {
"type": "CentralTransitive",
- "requested": "[3.0.1, )",
- "resolved": "3.0.1",
- "contentHash": "zKac6o3McDkjZOm51l8t5DmHX+1HlUZ4xzGjTd0StJMhsOYC0BK1EQaD51IdUQiLWDAsFPD6ES5P1hdTI5uQtg==",
+ "requested": "[3.1.1, )",
+ "resolved": "3.1.1",
+ "contentHash": "KYt4L25yAsLRVb9dhbfXGGcAQZQMbiLcTemDpCIiNaN+7DNygN+boUQXS5ByANyWzndJ5iKCgt2yWkspJXzwEQ==",
"dependencies": {
- "Microsoft.OpenApi": "3.0.1",
+ "Microsoft.OpenApi": "3.1.1",
"SharpYaml": "2.1.4",
"System.Text.Json": "8.0.5"
}