diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
index cc663fc98..c7d1cb30e 100644
--- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
+++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
@@ -10,7 +10,7 @@
Microsoft
Microsoft.OpenApi.Readers
Microsoft.OpenApi.Readers
- 1.2.1
+ 1.2.3
OpenAPI.NET Readers for JSON and YAML documents
© Microsoft Corporation. All rights reserved.
OpenAPI .NET
diff --git a/src/Microsoft.OpenApi.Readers/OpenApiTextReaderReader.cs b/src/Microsoft.OpenApi.Readers/OpenApiTextReaderReader.cs
index 107454796..c05456cec 100644
--- a/src/Microsoft.OpenApi.Readers/OpenApiTextReaderReader.cs
+++ b/src/Microsoft.OpenApi.Readers/OpenApiTextReaderReader.cs
@@ -45,7 +45,7 @@ public OpenApiDocument Read(TextReader input, out OpenApiDiagnostic diagnostic)
catch (YamlException ex)
{
diagnostic = new OpenApiDiagnostic();
- diagnostic.Errors.Add(new OpenApiError($"#char={ex.Start.Line}", ex.Message));
+ diagnostic.Errors.Add(new OpenApiError($"#line={ex.Start.Line}", ex.Message));
return new OpenApiDocument();
}
diff --git a/src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs b/src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs
index c6ebe24b3..033a94500 100644
--- a/src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs
+++ b/src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs
@@ -52,6 +52,7 @@ public override void Visit(OpenApiComponents components)
ResolveMap(components.Examples);
ResolveMap(components.Schemas);
ResolveMap(components.SecuritySchemes);
+ ResolveMap(components.Headers);
}
public override void Visit(IDictionary callbacks)
@@ -99,6 +100,15 @@ public override void Visit(OpenApiResponses responses)
ResolveMap(responses);
}
+ ///
+ /// Resolve all references to headers
+ ///
+ ///
+ public override void Visit(IDictionary headers)
+ {
+ ResolveMap(headers);
+ }
+
///
/// Resolve all references to SecuritySchemes
///
diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs
index 785ed6ee7..45d076370 100644
--- a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
+using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.ParseNodes;
@@ -164,6 +165,7 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List(formParameters.Where(p => p.Required).Select(p => p.Name))
@@ -201,9 +203,11 @@ internal static OpenApiRequestBody CreateRequestBody(
v => new OpenApiMediaType
{
Schema = bodyParameter.Schema
- })
+ }),
+ Extensions = bodyParameter.Extensions
};
+ requestBody.Extensions[OpenApiConstants.BodyName] = new OpenApiString(bodyParameter.Name);
return requestBody;
}
diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
index 8b5c990c1..c894aeb5a 100644
--- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
+++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
@@ -10,7 +10,7 @@
Microsoft
Microsoft.OpenApi
Microsoft.OpenApi
- 1.2.1
+ 1.2.3
.NET models with JSON and YAML writers for OpenAPI specification
© Microsoft Corporation. All rights reserved.
OpenAPI .NET
diff --git a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
index 11e6d8f70..3a29a88b1 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
@@ -560,6 +560,11 @@ public static class OpenApiConstants
///
public const string DefaultDescription = "Default Description";
+ ///
+ /// Field: BodyName extensions
+ ///
+ public const string BodyName = "x-bodyName";
+
///
/// Field: version3_0_0
///
diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
index 9e1a2ae5d..f17f81328 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
@@ -228,6 +228,12 @@ public void SerializeAsV2(IOpenApiWriter writer)
{
foreach (var property in RequestBody.Content.First().Value.Schema.Properties)
{
+ var paramName = property.Key;
+ var paramSchema = property.Value;
+ if (paramSchema.Type == "string" && paramSchema.Format == "binary") {
+ paramSchema.Type = "file";
+ paramSchema.Format = null;
+ }
parameters.Add(
new OpenApiFormDataParameter
{
@@ -235,23 +241,31 @@ public void SerializeAsV2(IOpenApiWriter writer)
Name = property.Key,
Schema = property.Value,
Required = RequestBody.Content.First().Value.Schema.Required.Contains(property.Key)
+
});
}
}
else
{
var content = RequestBody.Content.Values.FirstOrDefault();
+
var bodyParameter = new OpenApiBodyParameter
{
Description = RequestBody.Description,
// V2 spec actually allows the body to have custom name.
- // Our library does not support this at the moment.
+ // To allow round-tripping we use an extension to hold the name
Name = "body",
Schema = content?.Schema ?? new OpenApiSchema(),
Required = RequestBody.Required,
- Extensions = RequestBody.Extensions
+ Extensions = RequestBody.Extensions.ToDictionary(k => k.Key, v => v.Value) // Clone extensions so we can remove the x-bodyName extensions from the output V2 model.
};
+ if (bodyParameter.Extensions.ContainsKey(OpenApiConstants.BodyName))
+ {
+ bodyParameter.Name = (RequestBody.Extensions[OpenApiConstants.BodyName] as OpenApiString)?.Value ?? "body";
+ bodyParameter.Extensions.Remove(OpenApiConstants.BodyName);
+ }
+
parameters.Add(bodyParameter);
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
index 7866a1d63..a4b588599 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
+++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
@@ -150,6 +150,7 @@
Never
+
Never
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs
index 83620aa29..0deb72a5c 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs
@@ -7,6 +7,7 @@
using FluentAssertions;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Extensions;
+using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.ParseNodes;
using Microsoft.OpenApi.Readers.V2;
@@ -180,6 +181,9 @@ public class OpenApiOperationTests
Type = "object"
}
}
+ },
+ Extensions = {
+ [OpenApiConstants.BodyName] = new OpenApiString("petObject")
}
},
Responses = new OpenApiResponses
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs
new file mode 100644
index 000000000..60e3db6e4
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System.IO;
+using System.Linq;
+using FluentAssertions;
+using Microsoft.OpenApi.Any;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Readers.ParseNodes;
+using Microsoft.OpenApi.Readers.V3;
+using Xunit;
+
+namespace Microsoft.OpenApi.Readers.Tests.V3Tests
+{
+ [Collection("DefaultSettings")]
+ public class OpenApiResponseTests
+ {
+ private const string SampleFolderPath = "V3Tests/Samples/OpenApiResponse/";
+
+ [Fact]
+ public void ResponseWithReferencedHeaderShouldReferenceComponent()
+ {
+ using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "responseWithHeaderReference.yaml")))
+ {
+ var openApiDoc = new OpenApiStreamReader().Read(stream, out var diagnostic);
+
+ var response = openApiDoc.Components.Responses["Test"];
+
+ Assert.Same(response.Headers.First().Value, openApiDoc.Components.Headers.First().Value);
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithHeaderReference.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithHeaderReference.yaml
new file mode 100644
index 000000000..f2394282e
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithHeaderReference.yaml
@@ -0,0 +1,16 @@
+openapi: 3.0.0
+info:
+ title: Example of response referencing a header
+ version: 1.0.0
+components:
+ headers:
+ X-Test:
+ description: Test
+ schema:
+ type: string
+ responses:
+ Test:
+ description: Test Repsonse
+ headers:
+ X-Test:
+ $ref: '#/components/headers/X-Test'
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
index 2053a37d8..1a8ea432a 100755
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -1,4 +1,4 @@
-[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute(@"Microsoft.OpenApi.Readers.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute(@"Microsoft.OpenApi.Readers.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute(@"Microsoft.OpenApi.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6", FrameworkDisplayName=".NET Framework 4.6")]
namespace Microsoft.OpenApi.Any
@@ -352,6 +352,7 @@ namespace Microsoft.OpenApi.Models
public const string BasePath = "basePath";
public const string Basic = "basic";
public const string BearerFormat = "bearerFormat";
+ public const string BodyName = "x-bodyName";
public const string Callbacks = "callbacks";
public const string ClientCredentials = "clientCredentials";
public const string Components = "components";