-
Notifications
You must be signed in to change notification settings - Fork 262
Milestone
Description
Both @mikekistler and I have observed this bug while interacting with the new JsonNode-based example APIs in v2. The current logic tries to eagerly parse string JsonNodes as date times and write them as such when emitting the final document:
OpenAPI.NET/src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs
Lines 118 to 144 in e917e4c
if (valueKind == JsonValueKind.String && primitive is JsonValue jsonStrValue) | |
{ | |
if (jsonStrValue.TryGetValue<DateTimeOffset>(out var dto)) | |
{ | |
writer.WriteValue(dto); | |
} | |
else if (jsonStrValue.TryGetValue<DateTime>(out var dt)) | |
{ | |
writer.WriteValue(dt); | |
} | |
else if (jsonStrValue.TryGetValue<string>(out var strValue)) | |
{ | |
// check whether string is actual string or date time object | |
if (DateTimeOffset.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTimeOffset)) | |
{ | |
writer.WriteValue(dateTimeOffset); | |
} | |
else if (DateTime.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) | |
{ // order matters, DTO needs to be checked first!!! | |
writer.WriteValue(dateTime); | |
} | |
else | |
{ | |
writer.WriteValue(strValue); | |
} | |
} | |
} |
This can cause some rather unintended behaviors. For example, the current implementation casts example strings that are designated as a DateOnly
time to DateTime
based types. The current implementation will also errenously capture certain string examples (like a float 3.14
) as dates.
The following code:
using System.Text.Json.Nodes;
using System.IO;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Writers;
var schema = new OpenApiSchema()
{
Type = JsonSchemaType.String,
Example = JsonValue.Create("2024-01-02")
};
var schema2 = new OpenApiSchema()
{
Type = JsonSchemaType.String,
Example = JsonValue.Create("3.14")
};
var textWriter = new StringWriter();
var writer = new OpenApiJsonWriter(textWriter);
schema.SerializeAsV31(writer);
System.Console.WriteLine(textWriter.ToString());
textWriter = new StringWriter();
writer = new OpenApiJsonWriter(textWriter);
schema2.SerializeAsV31(writer);
System.Console.WriteLine(textWriter.ToString());
Produces:
{
"type": "string",
"example": "2024-01-02T00:00:00.0000000+00:00"
}
{
"type": "string",
"example": "2025-03-14T00:00:00.0000000+00:00"
}
When I would expect it to produce:
{
"type": "string",
"example": "2024-01-02"
}
{
"type": "string",
"example": "3.14"
}
mikekistler
Metadata
Metadata
Assignees
Labels
No labels