diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs
index 1e729f30a..ebe372d40 100644
--- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs
+++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs
@@ -109,6 +109,8 @@ public OpenApiReference ConvertToOpenApiReference(
}
// Where fragments point into a non-OpenAPI document, the id will be the complete fragment identifier
string id = segments[1];
+ var openApiReference = new OpenApiReference();
+
// $ref: externalSource.yaml#/Pet
if (id.StartsWith("/components/"))
{
@@ -127,13 +129,16 @@ public OpenApiReference ConvertToOpenApiReference(
}
id = localSegments[3];
}
-
- return new OpenApiReference
+ else
{
- ExternalResource = segments[0],
- Type = type,
- Id = id
- };
+ openApiReference.IsFragrament = true;
+ }
+
+ openApiReference.ExternalResource = segments[0];
+ openApiReference.Type = type;
+ openApiReference.Id = id;
+
+ return openApiReference;
}
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiReference.cs b/src/Microsoft.OpenApi/Models/OpenApiReference.cs
index ecc643dc3..e8798cc64 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiReference.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiReference.cs
@@ -45,6 +45,11 @@ public class OpenApiReference : IOpenApiSerializable
///
public bool IsLocal => ExternalResource == null;
+ ///
+ /// Gets a flag indicating whether a file is a valid OpenAPI document or a fragment
+ ///
+ public bool IsFragrament = false;
+
///
/// The OpenApiDocument that is hosting the OpenApiReference instance. This is used to enable dereferencing the reference.
///
@@ -196,7 +201,12 @@ private string GetExternalReferenceV3()
{
if (Id != null)
{
- return ExternalResource + "#/components/" + Type.GetDisplayName() + "/"+ Id;
+ if (IsFragrament)
+ {
+ return ExternalResource + "#" + Id;
+ }
+
+ return ExternalResource + "#/components/" + Type.GetDisplayName() + "/"+ Id;
}
return ExternalResource;
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 2e73118b2..b5d1167f3 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
+++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
@@ -149,6 +149,9 @@
Never
+
+ Never
+
Never
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
index 6fbb7065a..362609291 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
@@ -6,6 +6,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Text;
using System.Threading;
using FluentAssertions;
using Microsoft.OpenApi.Any;
@@ -1327,5 +1328,24 @@ public void HeaderParameterShouldAllowExample()
});
}
}
+
+ [Fact]
+ public void DoesNotChangeExternalReferences()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "documentWithExternalRefs.yaml"));
+
+ // Act
+ var doc = new OpenApiStreamReader(
+ new OpenApiReaderSettings { ReferenceResolution = ReferenceResolutionSetting.DoNotResolveReferences})
+ .Read(stream, out var diagnostic);
+
+ var externalRef = doc.Components.Schemas["Nested"].Properties["AnyOf"].AnyOf.First().Reference.ReferenceV3;
+ var externalRef2 = doc.Components.Schemas["Nested"].Properties["AnyOf"].AnyOf.Last().Reference.ReferenceV3;
+
+ // Assert
+ Assert.Equal("file:///C:/MySchemas.json#/definitions/ArrayObject", externalRef);
+ Assert.Equal("../foo/schemas.yaml#/components/schemas/Number", externalRef2);
+ }
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithExternalRefs.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithExternalRefs.yaml
new file mode 100644
index 000000000..c0b7b3a25
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithExternalRefs.yaml
@@ -0,0 +1,16 @@
+ openapi: 3.0.1
+ info:
+ title: anyOf-oneOf
+ license:
+ name: MIT
+ version: 1.0.0
+ paths: { }
+ components:
+ schemas:
+ Nested:
+ type: object
+ properties:
+ AnyOf:
+ anyOf:
+ - $ref: file:///C:/MySchemas.json#/definitions/ArrayObject
+ - $ref: ../foo/schemas.yaml#/components/schemas/Number
\ 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 75e12f480..4eb7a060d 100755
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -773,6 +773,7 @@ namespace Microsoft.OpenApi.Models
}
public class OpenApiReference : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiSerializable
{
+ public bool IsFragrament;
public OpenApiReference() { }
public OpenApiReference(Microsoft.OpenApi.Models.OpenApiReference reference) { }
public string ExternalResource { get; set; }