Skip to content

Commit ed5c771

Browse files
Merge pull request #1851 from microsoft/mk/fix-$ref-with-$id-serialization
Fix $ref with $id serialization
2 parents e0a3bb2 + 66fb599 commit ed5c771

File tree

6 files changed

+106
-9
lines changed

6 files changed

+106
-9
lines changed

src/Microsoft.OpenApi/Models/OpenApiReference.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public string ReferenceV3
9595
{
9696
return Id;
9797
}
98+
if (Id.StartsWith("http"))
99+
{
100+
return Id;
101+
}
98102

99103
return "#/components/" + Type.GetDisplayName() + "/" + Id;
100104
}
@@ -236,6 +240,11 @@ private string GetExternalReferenceV3()
236240
return ExternalResource + "#" + Id;
237241
}
238242

243+
if (Id.StartsWith("http"))
244+
{
245+
return Id;
246+
}
247+
239248
return ExternalResource + "#/components/" + Type.GetDisplayName() + "/" + Id;
240249
}
241250

src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
using Microsoft.OpenApi.Any;
54
using Microsoft.OpenApi.Interfaces;
65
using Microsoft.OpenApi.Writers;
76
using System;
87
using System.Collections.Generic;
9-
using System.Runtime;
108
using System.Text.Json.Nodes;
119

1210
namespace Microsoft.OpenApi.Models.References

src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@ private static (string, string) GetReferenceIdAndExternalResource(string pointer
157157
string refId = !pointer.Contains('#') ? pointer : refSegments.Last();
158158

159159
var isExternalResource = !refSegments.First().StartsWith("#");
160-
string externalResource = isExternalResource
161-
? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}"
162-
: null;
160+
string externalResource = null;
161+
if (isExternalResource && pointer.Contains('#'))
162+
{
163+
externalResource = $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}";
164+
}
163165

164166
return (refId, externalResource);
165167
}

test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@
4242
<DependentUpon>OpenApiCallbackReferenceTests.cs</DependentUpon>
4343
</None>
4444

45+
<None Update="Models\Samples\docWithDollarId.yaml">
46+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
47+
</None>
48+
4549
<None Update="Models\Samples\docWithReusableWebhooks.yaml">
4650
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
4751
</None>
4852

4953
<None Update="PublicApi\PublicApi.approved.txt" CopyToOutputDirectory="Always" />
5054
</ItemGroup>
51-
52-
<ItemGroup>
53-
<Folder Include="Models\Samples\" />
54-
</ItemGroup>
5555
</Project>

test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,5 +1642,54 @@ public void SerializeV31DocumentWithRefsInWebhooksWorks()
16421642
var actual = stringWriter.ToString();
16431643
actual.MakeLineBreaksEnvironmentNeutral().Should().BeEquivalentTo(expected.MakeLineBreaksEnvironmentNeutral());
16441644
}
1645+
1646+
[Fact]
1647+
public void SerializeDocWithDollarIdInDollarRefSucceeds()
1648+
{
1649+
var expected = @"openapi: '3.1.0'
1650+
info:
1651+
title: Simple API
1652+
version: 1.0.0
1653+
paths:
1654+
/box:
1655+
get:
1656+
responses:
1657+
'200':
1658+
description: OK
1659+
content:
1660+
application/json:
1661+
schema:
1662+
$ref: https://foo.bar/Box
1663+
/circle:
1664+
get:
1665+
responses:
1666+
'200':
1667+
description: OK
1668+
content:
1669+
application/json:
1670+
schema:
1671+
$ref: https://foo.bar/Circle
1672+
components:
1673+
schemas:
1674+
Box:
1675+
$id: https://foo.bar/Box
1676+
type: object
1677+
properties:
1678+
width:
1679+
type: number
1680+
height:
1681+
type: number
1682+
Circle:
1683+
$id: https://foo.bar/Circle
1684+
type: object
1685+
properties:
1686+
radius:
1687+
type: number
1688+
";
1689+
var doc = OpenApiDocument.Load("Models/Samples/docWithDollarId.yaml").OpenApiDocument;
1690+
1691+
var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_1);
1692+
actual.MakeLineBreaksEnvironmentNeutral().Should().BeEquivalentTo(expected.MakeLineBreaksEnvironmentNeutral());
1693+
}
16451694
}
16461695
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Simple API
4+
version: 1.0.0
5+
paths:
6+
/box:
7+
get:
8+
responses:
9+
'200':
10+
description: OK
11+
content:
12+
application/json:
13+
schema:
14+
$ref: https://foo.bar/Box
15+
/circle:
16+
get:
17+
responses:
18+
'200':
19+
description: OK
20+
content:
21+
application/json:
22+
schema:
23+
$ref: https://foo.bar/Circle
24+
components:
25+
schemas:
26+
Box:
27+
$id: https://foo.bar/Box
28+
type: object
29+
properties:
30+
width:
31+
type: number
32+
height:
33+
type: number
34+
Circle:
35+
$id: https://foo.bar/Circle
36+
type: object
37+
properties:
38+
radius:
39+
type: number

0 commit comments

Comments
 (0)