Skip to content

Commit 29b8144

Browse files
authored
Merge branch 'vnext' into dm/commandline
2 parents 6926b6d + 6f5e63c commit 29b8144

File tree

6 files changed

+368
-13
lines changed

6 files changed

+368
-13
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ Project Objectives
1919
- Provide OpenAPI description writers for both V2 and V3 specification formats.
2020
- Enable developers to create Readers that translate different data formats into OpenAPI descriptions.
2121

22+
# Installation
23+
24+
- Install core Nuget package `Microsoft.OpenApi`
25+
- Install readers Nuget package `Microsoft.OpenApi.Readers`
26+
2227
# Processors
2328
The OpenAPI.NET project holds the base object model for representing OpenAPI documents as .NET objects. Some developers have found the need to write processors that convert other data formats into this OpenAPI.NET object model. We'd like to curate that list of processors in this section of the readme.
2429

src/Microsoft.OpenApi.Readers/ParseNodes/OpenApiAnyConverter.cs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,61 @@ public static IOpenApiAny GetSpecificOpenApiAny(IOpenApiAny openApiAny, OpenApiS
5656
}
5757

5858
var value = ((OpenApiString)openApiAny).Value;
59+
var type = schema?.Type;
60+
var format = schema?.Format;
5961

60-
// For explicit strings only try to guess if it's a DateTimeOffset
6162
if (((OpenApiString)openApiAny).IsExplicit())
6263
{
63-
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
64+
// More narrow type detection for explicit strings, only check types that are passed as strings
65+
if (schema == null)
6466
{
65-
return new OpenApiDateTime(dateTimeValue);
67+
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
68+
{
69+
return new OpenApiDateTime(dateTimeValue);
70+
}
71+
}
72+
else if (type == "string")
73+
{
74+
if (format == "byte")
75+
{
76+
try
77+
{
78+
return new OpenApiByte(Convert.FromBase64String(value));
79+
}
80+
catch (FormatException)
81+
{ }
82+
}
83+
84+
if (format == "binary")
85+
{
86+
try
87+
{
88+
return new OpenApiBinary(Encoding.UTF8.GetBytes(value));
89+
}
90+
catch (EncoderFallbackException)
91+
{ }
92+
}
93+
94+
if (format == "date")
95+
{
96+
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateValue))
97+
{
98+
return new OpenApiDate(dateValue.Date);
99+
}
100+
}
101+
102+
if (format == "date-time")
103+
{
104+
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
105+
{
106+
return new OpenApiDateTime(dateTimeValue);
107+
}
108+
}
109+
110+
if (format == "password")
111+
{
112+
return new OpenApiPassword(value);
113+
}
66114
}
67115

68116
return openApiAny;
@@ -107,9 +155,6 @@ public static IOpenApiAny GetSpecificOpenApiAny(IOpenApiAny openApiAny, OpenApiS
107155
}
108156
else
109157
{
110-
var type = schema.Type;
111-
var format = schema.Format;
112-
113158
if (type == "integer" && format == "int32")
114159
{
115160
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
@@ -202,7 +247,7 @@ public static IOpenApiAny GetSpecificOpenApiAny(IOpenApiAny openApiAny, OpenApiS
202247

203248
if (type == "string")
204249
{
205-
return new OpenApiString(value);
250+
return openApiAny;
206251
}
207252

208253
if (type == "boolean")

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
252252
// deprecated
253253
writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false);
254254

255+
var extensionsClone = new Dictionary<string, IOpenApiExtension>(Extensions);
256+
255257
// schema
256258
if (this is OpenApiBodyParameter)
257259
{
@@ -283,7 +285,20 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
283285
// uniqueItems
284286
// enum
285287
// multipleOf
286-
Schema?.WriteAsItemsProperties(writer);
288+
if (Schema != null)
289+
{
290+
Schema.WriteAsItemsProperties(writer);
291+
292+
if (Schema.Extensions != null)
293+
{
294+
foreach (var key in Schema.Extensions.Keys)
295+
{
296+
// The extension will already have been serialized as part of the call to WriteAsItemsProperties above,
297+
// so remove it from the cloned collection so we don't write it again.
298+
extensionsClone.Remove(key);
299+
}
300+
}
301+
}
287302

288303
// allowEmptyValue
289304
writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false);
@@ -307,7 +322,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
307322

308323

309324
// extensions
310-
writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);
325+
writer.WriteExtensions(extensionsClone, OpenApiSpecVersion.OpenApi2_0);
311326

312327
writer.WriteEndObject();
313328
}

src/Microsoft.OpenApi/Models/OpenApiResponse.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
124124
// description
125125
writer.WriteRequiredProperty(OpenApiConstants.Description, Description);
126126

127+
var extensionsClone = new Dictionary<string, IOpenApiExtension>(Extensions);
128+
127129
if (Content != null)
128130
{
129131
var mediatype = Content.FirstOrDefault();
@@ -152,14 +154,23 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
152154

153155
writer.WriteEndObject();
154156
}
157+
158+
writer.WriteExtensions(mediatype.Value.Extensions, OpenApiSpecVersion.OpenApi2_0);
159+
160+
foreach (var key in mediatype.Value.Extensions.Keys)
161+
{
162+
// The extension will already have been serialized as part of the call above,
163+
// so remove it from the cloned collection so we don't write it again.
164+
extensionsClone.Remove(key);
165+
}
155166
}
156167
}
157168

158169
// headers
159170
writer.WriteOptionalMap(OpenApiConstants.Headers, Headers, (w, h) => h.SerializeAsV2(w));
160171

161172
// extension
162-
writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);
173+
writer.WriteExtensions(extensionsClone, OpenApiSpecVersion.OpenApi2_0);
163174

164175
writer.WriteEndObject();
165176
}

0 commit comments

Comments
 (0)