从大型 OpenAPI 文档或使用 NewtonSoft 获取 JSON 模式并解析引用
Get the JSON Schema's from a large OpenAPI Document OR using NewtonSoft and resolve refs
我目前正在寻找从大型 OpenAPI 规范中提取所有 JSON 模式。我一直在使用以下 NuGet 包:
Microsoft.OpenApi v1.3.1
Microsoft.OpenApi.Readers v1.3.1
我希望使用这些来解析大型 Open API 规范并提取所有 JSON 模式,我能够将其解析为 'Microsoft.OpenApi.Models.OpenApiSchema' 对象。但我似乎无法从这些对象创建 JSON 架构并将其写入文件。
目前我有以下情况:
using (FileStream fs = File.Open(file.FullName, FileMode.Open))
{
var openApiDocument = new OpenApiStreamReader().Read(fs, out var diagnostic);
foreach (var schema in openApiDocument.Components.Schemas)
{
var schemaName = schema.Key;
var schemaContent = schema.Value;
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schemaName + "-Schema.json");
var outputString = schemaContent.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json);
using (TextWriter sw = new StreamWriter(outputPath, true))
{
sw.Write(outputString);
sw.Close();
}
}
}
schemaContent
似乎具有架构的所有相关属性,但我似乎无法确定将它从该对象获取到 JSON 的下一步模式。我确定我遗漏了一些简单的东西,所以任何见解都将不胜感激。
已更新
我想了想,采用了稍微不同的方法,改用 NewtonSoft Json。
var OpenApitext = File.ReadAllText(file.FullName, Encoding.UTF8);
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
MetadataPropertyHandling = MetadataPropertyHandling.Ignore, //ign
Formatting = Newtonsoft.Json.Formatting.Indented
};
dynamic openApiJson = JsonConvert.DeserializeObject<ExpandoObject>(OpenApitext, settings);
if (openApiJson?.components?.schemas != null)
{
foreach (var schema in openApiJson.components.schemas)
{
var schemaString = JsonConvert.SerializeObject(schema, settings);
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schema.Name + "-Schema.json");
using (TextWriter sw = new StreamWriter(outputPath, true))
{
sw.Write(schemaString);
sw.Close();
}
}
}
现在这将允许我创建 JSON 架构并将其写入文件,但它不想解析引用。查看 API 规范,所有引用似乎都是 API 规范的本地引用。在循环浏览模式并将它们写入文件之前,我需要做什么才能解析 Open API 规范中的所有引用?我做了一些研究,有些人似乎自己构建了此功能,但他们总是使用 class 对象作为支持它的方式,我在这里无法做到这一点。
我最终通过 microsoft/OpenAPI.NET GitHub 存储库联系到了我。通过 coincidence/happenstance 我从那里和这里得到了同一个人的回复。所以,谢谢 Darrel,你帮助我解决了上述让我相当困惑的场景。最后我知道是我没有完全正确地实现它。
作为参考,下面的用例是采用相当大的 OpenAPI 规范 (Json) 并提取引用的 JSON 模式,同时确保 JSON 指针 ($ref, $id) 等在写入文件时得到解决。
我想采用这种方法的原因是,由于 OpenAPI 规范的规模,我必须使用它来使用 pre-built 工具(例如可以提取模式的 Postman)非常困难。
我实现的最终代码片段,有几行有点粗糙,我会在周末整理一下。
Console.WriteLine($"Processing file: {file.FullName}");
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file.FullName);
var fileExtension = Path.GetExtension(file.FullName);
var reader = new OpenApiStreamReader();
var result = await reader.ReadAsync(new FileStream(file.FullName, FileMode.Open));
foreach (var schemaEntry in result.OpenApiDocument.Components.Schemas)
{
var schemaFileName = schemaEntry.Key + ".json";
Console.WriteLine("Creating " + schemaFileName);
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schemaFileName + "-Schema.json");
using FileStream? fileStream = new FileStream(outputPath, FileMode.CreateNew);
var writerSettings = new OpenApiWriterSettings() { InlineLocalReferences = true, InlineExternalReferences = true };
using var writer = new StreamWriter(fileStream);
schemaEntry.Value.SerializeAsV2WithoutReference(new OpenApiJsonWriter(writer, writerSettings));
}
我目前正在寻找从大型 OpenAPI 规范中提取所有 JSON 模式。我一直在使用以下 NuGet 包:
Microsoft.OpenApi v1.3.1
Microsoft.OpenApi.Readers v1.3.1
我希望使用这些来解析大型 Open API 规范并提取所有 JSON 模式,我能够将其解析为 'Microsoft.OpenApi.Models.OpenApiSchema' 对象。但我似乎无法从这些对象创建 JSON 架构并将其写入文件。
目前我有以下情况:
using (FileStream fs = File.Open(file.FullName, FileMode.Open))
{
var openApiDocument = new OpenApiStreamReader().Read(fs, out var diagnostic);
foreach (var schema in openApiDocument.Components.Schemas)
{
var schemaName = schema.Key;
var schemaContent = schema.Value;
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schemaName + "-Schema.json");
var outputString = schemaContent.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json);
using (TextWriter sw = new StreamWriter(outputPath, true))
{
sw.Write(outputString);
sw.Close();
}
}
}
schemaContent
似乎具有架构的所有相关属性,但我似乎无法确定将它从该对象获取到 JSON 的下一步模式。我确定我遗漏了一些简单的东西,所以任何见解都将不胜感激。
已更新
我想了想,采用了稍微不同的方法,改用 NewtonSoft Json。
var OpenApitext = File.ReadAllText(file.FullName, Encoding.UTF8);
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
MetadataPropertyHandling = MetadataPropertyHandling.Ignore, //ign
Formatting = Newtonsoft.Json.Formatting.Indented
};
dynamic openApiJson = JsonConvert.DeserializeObject<ExpandoObject>(OpenApitext, settings);
if (openApiJson?.components?.schemas != null)
{
foreach (var schema in openApiJson.components.schemas)
{
var schemaString = JsonConvert.SerializeObject(schema, settings);
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schema.Name + "-Schema.json");
using (TextWriter sw = new StreamWriter(outputPath, true))
{
sw.Write(schemaString);
sw.Close();
}
}
}
现在这将允许我创建 JSON 架构并将其写入文件,但它不想解析引用。查看 API 规范,所有引用似乎都是 API 规范的本地引用。在循环浏览模式并将它们写入文件之前,我需要做什么才能解析 Open API 规范中的所有引用?我做了一些研究,有些人似乎自己构建了此功能,但他们总是使用 class 对象作为支持它的方式,我在这里无法做到这一点。
我最终通过 microsoft/OpenAPI.NET GitHub 存储库联系到了我。通过 coincidence/happenstance 我从那里和这里得到了同一个人的回复。所以,谢谢 Darrel,你帮助我解决了上述让我相当困惑的场景。最后我知道是我没有完全正确地实现它。
作为参考,下面的用例是采用相当大的 OpenAPI 规范 (Json) 并提取引用的 JSON 模式,同时确保 JSON 指针 ($ref, $id) 等在写入文件时得到解决。
我想采用这种方法的原因是,由于 OpenAPI 规范的规模,我必须使用它来使用 pre-built 工具(例如可以提取模式的 Postman)非常困难。
我实现的最终代码片段,有几行有点粗糙,我会在周末整理一下。
Console.WriteLine($"Processing file: {file.FullName}");
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file.FullName);
var fileExtension = Path.GetExtension(file.FullName);
var reader = new OpenApiStreamReader();
var result = await reader.ReadAsync(new FileStream(file.FullName, FileMode.Open));
foreach (var schemaEntry in result.OpenApiDocument.Components.Schemas)
{
var schemaFileName = schemaEntry.Key + ".json";
Console.WriteLine("Creating " + schemaFileName);
var outputDir = Path.Combine(outputDirectory.FullName, fileNameWithoutExtension);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
var outputPath = Path.Combine(outputDir, schemaFileName + "-Schema.json");
using FileStream? fileStream = new FileStream(outputPath, FileMode.CreateNew);
var writerSettings = new OpenApiWriterSettings() { InlineLocalReferences = true, InlineExternalReferences = true };
using var writer = new StreamWriter(fileStream);
schemaEntry.Value.SerializeAsV2WithoutReference(new OpenApiJsonWriter(writer, writerSettings));
}