private void WriteValueRecursive(OpenApiYamlWriter writer, object value) { if (value == null || value.GetType().IsPrimitive || value is decimal || value is string || value is DateTimeOffset || value is DateTime) { writer.WriteValue(value); } else if (value.GetType().IsGenericType&& (typeof(IDictionary <,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition()) || typeof(Dictionary <,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition()))) { writer.WriteStartObject(); foreach (var elementValue in (dynamic)(value)) { writer.WritePropertyName(elementValue.Key); WriteValueRecursive(writer, elementValue.Value); } writer.WriteEndObject(); } else if (typeof(IEnumerable).IsAssignableFrom(value.GetType())) { writer.WriteStartArray(); foreach (var elementValue in (IEnumerable)value) { WriteValueRecursive(writer, elementValue); } writer.WriteEndArray(); } }
private static IActionResult CreateResult(string openApiVersion, OpenApiDocument subset, string format) { var sr = new StringWriter(); OpenApiWriterBase writer; if (format == "yaml") { writer = new OpenApiYamlWriter(sr); } else { writer = new OpenApiJsonWriter(sr); } if (openApiVersion == "2") { subset.SerializeAsV2(writer); } else { subset.SerializeAsV3(writer); } var output = sr.GetStringBuilder().ToString(); return(new ContentResult() { Content = output, ContentType = "application/json" }); }
/// <summary> /// Create a representation of the OpenApiDocument to return from an API /// </summary> /// <param name="subset">OpenAPI document</param> /// <param name="openApiVersion"></param> /// <param name="format"></param> /// <returns></returns> public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, string openApiVersion, string format) { var stream = new MemoryStream(); var sr = new StreamWriter(stream); OpenApiWriterBase writer; if (format == "yaml") { writer = new OpenApiYamlWriter(sr); } else { writer = new OpenApiJsonWriter(sr); } if (openApiVersion == "2") { subset.SerializeAsV2(writer); } else { subset.SerializeAsV3(writer); } sr.Flush(); stream.Position = 0; return(stream); }
/// <summary> /// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document using /// the given stream, specification version and the format. /// </summary> /// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam> /// <param name="element">The Open API element.</param> /// <param name="stream">The given stream.</param> /// <param name="specVersion">The Open API specification version.</param> /// <param name="format">The output format (JSON or YAML).</param> public static void Serialize <T>( this T element, Stream stream, OpenApiSpecVersion specVersion, OpenApiFormat format) where T : IOpenApiSerializable { if (stream == null) { throw Error.ArgumentNull(nameof(stream)); } IOpenApiWriter writer; switch (format) { case OpenApiFormat.Json: writer = new OpenApiJsonWriter(new StreamWriter(stream)); break; case OpenApiFormat.Yaml: writer = new OpenApiYamlWriter(new StreamWriter(stream)); break; default: throw new OpenApiException(string.Format(SRResource.OpenApiFormatNotSupported, format)); } element.Serialize(writer, specVersion); }
public void WriteInlineSchemaV2() { var doc = CreateDocWithSimpleSchemaToInline(); var expected = @"swagger: '2.0' info: title: Demo version: 1.0.0 paths: /: get: produces: - application/json responses: '200': description: OK schema: type: object"; var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); // Act doc.SerializeAsV2(writer); var actual = outputString.GetStringBuilder().ToString(); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); expected = expected.MakeLineBreaksEnvironmentNeutral(); Assert.Equal(expected, actual); }
public void WriteStringListAsYamlShouldMatchExpected(string[] stringValues, string expectedYaml) { // Arrange var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString); // Act writer.WriteStartArray(); foreach (var stringValue in stringValues) { writer.WriteValue(stringValue); } writer.WriteEndArray(); writer.Flush(); var actualYaml = outputString.GetStringBuilder() .ToString() .MakeLineBreaksEnvironmentNeutral(); expectedYaml = expectedYaml.MakeLineBreaksEnvironmentNeutral(); // Assert actualYaml.Should().Be(expectedYaml); }
public static string GetValueString(this IOpenApiPrimitive primitive) { using var sb = new StringWriter(); var writer = new OpenApiYamlWriter(sb); primitive.Write(writer, OpenApiSpecVersion.OpenApi3_0); return(sb.ToString()); }
public string AsYaml(OpenApiDocument document) { StringWriter writer = new StringWriter(); OpenApiYamlWriter yamlWriter = new OpenApiYamlWriter(writer); document.SerializeAsV3(yamlWriter); return(writer.ToString()); }
public void WriteInlineRecursiveSchema() { // Arrange var doc = CreateDocWithRecursiveSchemaReference(); var expected = @"openapi: 3.0.1 info: title: Demo version: 1.0.0 paths: /: get: responses: '200': description: OK content: application/json: schema: type: object properties: children: $ref: '#/components/schemas/thing' related: type: integer components: schemas: thing: type: object properties: children: type: object properties: children: $ref: '#/components/schemas/thing' related: type: integer related: type: integer"; // Component schemas that are there due to cycles are still inlined because the items they reference may not exist in the components because they don't have cycles. var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); // Act doc.SerializeAsV3(writer); var actual = outputString.GetStringBuilder().ToString(); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); expected = expected.MakeLineBreaksEnvironmentNeutral(); Assert.Equal(expected, actual); }
private static string Write(Action <OpenApiYamlWriter> action) { MemoryStream stream = new MemoryStream(); OpenApiYamlWriter writer = new OpenApiYamlWriter(new StreamWriter(stream)); action(writer); writer.Flush(); stream.Position = 0; return(new StreamReader(stream).ReadToEnd()); }
private static OpenApiDocument Clone(OpenApiDocument subsetOpenApiDocument) { var stream = new MemoryStream(); var writer = new OpenApiYamlWriter(new StreamWriter(stream)); subsetOpenApiDocument.SerializeAsV3(writer); writer.Flush(); stream.Position = 0; var reader = new OpenApiStreamReader(); return(reader.Read(stream, out OpenApiDiagnostic diag)); }
private static void CreateOpenApiDocument(IEnumerable <ApiMethod> identifiedMethods, string filepath) { var fi = new FileInfo(filepath); Console.WriteLine($"Creating OpenAPI document at {fi.FullName}…"); var document = CreateOpenApiDocument(identifiedMethods); var targetYaml = File.CreateText(fi.FullName); var w = new OpenApiYamlWriter(targetYaml); document.SerializeAsV3(w); targetYaml.Flush(); }
public RestResponse OpenApiYaml() { var doc = GetAPIDoc(); var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString); doc.SerializeAsV3(writer); return(new RestResponse() { Content = Encoding.UTF8.GetBytes(outputString.ToString()), ContentType = "text/yaml" }); }
public void WriteStringWithSpecialCharactersAsYamlWorks(string input, string expected) { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputStringWriter); // Act writer.WriteValue(input); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert actual.Should().Be(expected); }
public void CanWriterYaml() { OpenApiDocument doc = new OpenApiDocument(); var builder = new StringBuilder(); StringWriter sw = new StringWriter(builder); IOpenApiWriter writer = new OpenApiYamlWriter(sw, new OpenApiWriterSettings()); doc.Write(writer); sw.Flush(); output.WriteLine(sw.ToString()); }
public void WriteDateTimeAsJsonShouldMatchExpected(DateTimeOffset dateTimeOffset) { // Arrange var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString); // Act writer.WriteValue(dateTimeOffset); var writtenString = outputString.GetStringBuilder().ToString(); var expectedString = " '" + dateTimeOffset.ToString("o") + "'"; // Assert writtenString.Should().Be(expectedString); }
public void WriteMapAsYamlShouldMatchExpected(IDictionary <string, object> inputMap, string expectedYaml) { // Arrange var outputString = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputString); // Act WriteValueRecursive(writer, inputMap); var actualYaml = outputString.ToString(); // Assert actualYaml = actualYaml.MakeLineBreaksEnvironmentNeutral(); expectedYaml = expectedYaml.MakeLineBreaksEnvironmentNeutral(); actualYaml.Should().Be(expectedYaml); }
public void SerializeBasicTagAsV3YamlWithoutReferenceWorks() { // Arrange var outputStringWriter = new StringWriter(); var writer = new OpenApiYamlWriter(outputStringWriter); var expected = "{ }"; // Act BasicTag.SerializeAsV3WithoutReference(writer); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual.Should().Be(expected); }
/// <summary> /// Create a representation of the OpenApiDocument to return from an API /// </summary> /// <param name="subset">OpenAPI document.</param> /// <param name="styleOptions">The modal object containing the required styling options.</param> /// <returns>A memory stream.</returns> public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, OpenApiStyleOptions styleOptions) { var stream = new MemoryStream(); var sr = new StreamWriter(stream); OpenApiWriterBase writer; if (styleOptions.OpenApiFormat == Constants.OpenApiConstants.Format_Yaml) { if (styleOptions.InlineLocalReferences) { writer = new OpenApiYamlWriter(sr, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); } else { writer = new OpenApiYamlWriter(sr); } } else // json { if (styleOptions.InlineLocalReferences) { writer = new OpenApiJsonWriter(sr, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); } else { writer = new OpenApiJsonWriter(sr); } } if (styleOptions.OpenApiVersion == Constants.OpenApiConstants.OpenApiVersion_2) { subset.SerializeAsV2(writer); } else { subset.SerializeAsV3(writer); } sr.Flush(); stream.Position = 0; return(stream); }
/// <summary> /// Create a representation of the OpenApiDocument to return from an API /// </summary> /// <param name="subset">OpenAPI document</param> /// <param name="openApiVersion"></param> /// <param name="format">The format of the OpenAPI doc.</param> /// <param name="style">The styling preference of the OpenAPI doc.</param> /// <returns></returns> public static MemoryStream SerializeOpenApiDocument(OpenApiDocument subset, string openApiVersion, string format, OpenApiStyle style) { var stream = new MemoryStream(); var sr = new StreamWriter(stream); OpenApiWriterBase writer; if (format == "yaml") { if (style == OpenApiStyle.PowerPlatform) { writer = new OpenApiYamlWriter(sr, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); } else { writer = new OpenApiYamlWriter(sr); } } else { if (style == OpenApiStyle.PowerPlatform) { writer = new OpenApiJsonWriter(sr, new OpenApiWriterSettings { ReferenceInline = ReferenceInlineSetting.InlineLocalReferences }); } else { writer = new OpenApiJsonWriter(sr); } } if (openApiVersion == "2") { subset.SerializeAsV2(writer); } else { subset.SerializeAsV3(writer); } sr.Flush(); stream.Position = 0; return(stream); }
public void SerializeReferencedTagAsV2YamlWorks() { // Arrange var outputStringWriter = new StringWriter(); var writer = new OpenApiYamlWriter(outputStringWriter); var expected = @" pet"; // Act ReferencedTag.SerializeAsV2(writer); writer.Flush(); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual.Should().Be(expected); }
internal static string Write(OpenApiTarget target, Action <IOpenApiWriter> action) { MemoryStream stream = new MemoryStream(); IOpenApiWriter writer; if (target == OpenApiTarget.Yaml) { writer = new OpenApiYamlWriter(new StreamWriter(stream)); } else { writer = new OpenApiJsonWriter(new StreamWriter(stream)); } action(writer); writer.Flush(); stream.Position = 0; return(new StreamReader(stream).ReadToEnd()); }
public void WriteStringWithNewlineCharactersInArrayAsYamlWorks(string input, string expected) { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); var writer = new OpenApiYamlWriter(outputStringWriter) { UseLiteralStyle = true, }; // Act writer.WriteStartArray(); writer.WriteValue(input); var actual = outputStringWriter.GetStringBuilder().ToString() // Normalize newline for cross platform .Replace("\r", ""); // Assert actual.Should().Be(expected); }
private async Task RespondWithSwaggerYaml(HttpResponse response, OpenApiDocument swagger) { response.StatusCode = 200; response.ContentType = "text/yaml;charset=utf-8"; using (var textWriter = new StringWriter(CultureInfo.InvariantCulture)) { var yamlWriter = new OpenApiYamlWriter(textWriter); if (_options.SerializeAsV2) { swagger.SerializeAsV2(yamlWriter); } else { swagger.SerializeAsV3(yamlWriter); } await response.WriteAsync(textWriter.ToString(), new UTF8Encoding(false)); } }
public void SerializeAdvancedTagAsV2YamlWithoutReferenceWorks() { // Arrange var outputStringWriter = new StringWriter(); var writer = new OpenApiYamlWriter(outputStringWriter); var expected = @"name: pet description: Pets operations externalDocs: description: Find more info here url: https://example.com x-tag-extension: "; // Act AdvancedTag.SerializeAsV2WithoutReference(writer); writer.Flush(); var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert actual = actual.MakeLineBreaksEnvironmentNeutral(); expected = expected.MakeLineBreaksEnvironmentNeutral(); actual.Should().Be(expected); }
static int Main(string[] args) { // Helper to simplify command line parsing etc. var runner = new CommandRunner("dotnet swagger", "Swashbuckle (Swagger) Command Line Tools", Console.Out); // NOTE: The "dotnet swagger tofile" command does not serve the request directly. Instead, it invokes a corresponding // command (called _tofile) via "dotnet exec" so that the runtime configuration (*.runtimeconfig & *.deps.json) of the // provided startupassembly can be used instead of the tool's. This is neccessary to successfully load the // startupassembly and it's transitive dependencies. See https://github.com/dotnet/coreclr/issues/13277 for more. // > dotnet swagger tofile ... runner.SubCommand("tofile", "retrieves Swagger from a startup assembly, and writes to file ", c => { c.Argument("startupassembly", "relative path to the application's startup assembly"); c.Argument("swaggerdoc", "name of the swagger doc you want to retrieve, as configured in your startup class"); c.Option("--output", "relative path where the Swagger will be output, defaults to stdout"); c.Option("--host", "a specific host to include in the Swagger output"); c.Option("--basepath", "a specific basePath to include in the Swagger output"); c.Option("--serializeasv2", "output Swagger in the V2 format rather than V3", true); c.Option("--yaml", "exports swagger in a yaml format", true); c.OnRun((namedArgs) => { var depsFile = namedArgs["startupassembly"].Replace(".dll", ".deps.json"); var runtimeConfig = namedArgs["startupassembly"].Replace(".dll", ".runtimeconfig.json"); var subProcess = Process.Start("dotnet", string.Format( "exec --depsfile {0} --runtimeconfig {1} {2} _{3}", // note the underscore EscapePath(depsFile), EscapePath(runtimeConfig), EscapePath(typeof(Program).GetTypeInfo().Assembly.Location), string.Join(" ", args) )); subProcess.WaitForExit(); return(subProcess.ExitCode); }); }); // > dotnet swagger _tofile ... (* should only be invoked via "dotnet exec") runner.SubCommand("_tofile", "", c => { c.Argument("startupassembly", ""); c.Argument("swaggerdoc", ""); c.Option("--output", ""); c.Option("--host", ""); c.Option("--basepath", ""); c.Option("--serializeasv2", "", true); c.Option("--yaml", "", true); c.OnRun((namedArgs) => { // 1) Configure host with provided startupassembly var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath( Path.Combine(Directory.GetCurrentDirectory(), namedArgs["startupassembly"])); // 2) Build a web host to serve the request var serviceProvider = GetServiceProvider(startupAssembly); // 3) Retrieve Swagger via configured provider var swaggerProvider = serviceProvider.GetRequiredService <ISwaggerProvider>(); var swagger = swaggerProvider.GetSwagger( namedArgs["swaggerdoc"], namedArgs.ContainsKey("--host") ? namedArgs["--host"] : null, namedArgs.ContainsKey("--basepath") ? namedArgs["--basepath"] : null); // 4) Serialize to specified output location or stdout var outputPath = namedArgs.ContainsKey("--output") ? Path.Combine(Directory.GetCurrentDirectory(), namedArgs["--output"]) : null; using (var streamWriter = (outputPath != null ? File.CreateText(outputPath) : Console.Out)) { IOpenApiWriter writer; if (namedArgs.ContainsKey("--yaml")) { writer = new OpenApiYamlWriter(streamWriter); } else { writer = new OpenApiJsonWriter(streamWriter); } if (namedArgs.ContainsKey("--serializeasv2")) { swagger.SerializeAsV2(writer); } else { swagger.SerializeAsV3(writer); } if (outputPath != null) { Console.WriteLine($"Swagger JSON/YAML succesfully written to {outputPath}"); } } return(0); }); }); return(runner.Run(args)); }
public static void ProcessOpenApiDocument( FileInfo input, FileInfo output, OpenApiSpecVersion version, OpenApiFormat format, bool inline) { OpenApiDocument document; using (Stream stream = input.OpenRead()) { document = new OpenApiStreamReader(new OpenApiReaderSettings { ReferenceResolution = ReferenceResolutionSetting.ResolveLocalReferences, RuleSet = ValidationRuleSet.GetDefaultRuleSet() } ).Read(stream, out var context); if (context.Errors.Count != 0) { var errorReport = new StringBuilder(); foreach (var error in context.Errors) { errorReport.AppendLine(error.ToString()); } throw new ArgumentException(String.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray())); } } using (var outputStream = output?.Create()) { TextWriter textWriter; if (outputStream != null) { textWriter = new StreamWriter(outputStream); } else { textWriter = Console.Out; } var settings = new OpenApiWriterSettings() { ReferenceInline = inline == true ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences }; IOpenApiWriter writer; switch (format) { case OpenApiFormat.Json: writer = new OpenApiJsonWriter(textWriter, settings); break; case OpenApiFormat.Yaml: writer = new OpenApiYamlWriter(textWriter, settings); break; default: throw new ArgumentException("Unknown format"); } document.Serialize(writer, version); textWriter.Flush(); } }