Is there an existing issue for this?
Describe the bug
Examples that are returned as part of .MapOpenApi() are formatted using CultureInfo.CurrentCulture in such a way that on a system with e.g. a german locale floating point numbers are output with a comma as a decimal symbol, which results in an invalid JSON response.
Expected Behavior
OpenApi examples should be written using a fixed IFormatProvider which results in valid JSON.
Steps To Reproduce
park-jasper/aspnetcore-openapi-format-issue
run the single project in this solution and query /openapi/v1.json
This returns the following document:
{
"openapi": "3.0.1",
"info": {
"title": "OpenApiFormatIssue | v1",
"version": "1.0.0"
},
"servers": [
{
"url": "https://localhost:7126"
},
{
"url": "http://localhost:5058"
}
],
"paths": {
"/": {
"get": {
"tags": [
"OpenApiFormatIssue"
],
"operationId": "ExampleEndpoint",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiResponse"
},
"examples": {
"FormatIssue": {
"value": 1,234
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"ApiResponse": {
"required": [
"value"
],
"type": "object",
"properties": {
"value": {
"type": "number",
"format": "double"
}
}
}
}
},
"tags": [
{
"name": "OpenApiFormatIssue"
}
]
}
Exceptions (if any)
No response
.NET Version
9.0.103
Anything else?
ASP.NET Core version 9.0.2
-- Workaround --
I can set CultureInfo.DefaultThreadCultureInfo to e.g. CultureInfo.InvariantCulture to circumvent this, because the TextWriter takes that as a fallback, but having to globally set this is not my ideal solution
-- Suggestion --
The code of interest is this one: https://github.com/dotnet/aspnetcore/blob/main/src/OpenApi/src/Extensions/OpenApiEndpointRouteBuilderExtensions.cs#L57
Here an Utf8BufferTextWriter is retrieved, and it in turn inherits from TextWriter.
TextWriter offers a constructor that takes an IFormatProvider, but Utf8BufferTextWriter implicitly calls the default constructor instead which does not set an IFormatProvider, and the default of CultureInfo.CurrentCulture is used
Is there an existing issue for this?
Describe the bug
Examples that are returned as part of
.MapOpenApi()are formatted usingCultureInfo.CurrentCulturein such a way that on a system with e.g. a german locale floating point numbers are output with a comma as a decimal symbol, which results in an invalid JSON response.Expected Behavior
OpenApi examples should be written using a fixed
IFormatProviderwhich results in valid JSON.Steps To Reproduce
park-jasper/aspnetcore-openapi-format-issue
run the single project in this solution and query /openapi/v1.json
This returns the following document:
{ "openapi": "3.0.1", "info": { "title": "OpenApiFormatIssue | v1", "version": "1.0.0" }, "servers": [ { "url": "https://localhost:7126" }, { "url": "http://localhost:5058" } ], "paths": { "/": { "get": { "tags": [ "OpenApiFormatIssue" ], "operationId": "ExampleEndpoint", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiResponse" }, "examples": { "FormatIssue": { "value": 1,234 } } } } } } } } }, "components": { "schemas": { "ApiResponse": { "required": [ "value" ], "type": "object", "properties": { "value": { "type": "number", "format": "double" } } } } }, "tags": [ { "name": "OpenApiFormatIssue" } ] }Exceptions (if any)
No response
.NET Version
9.0.103
Anything else?
ASP.NET Core version 9.0.2
-- Workaround --
I can set
CultureInfo.DefaultThreadCultureInfoto e.g.CultureInfo.InvariantCultureto circumvent this, because theTextWritertakes that as a fallback, but having to globally set this is not my ideal solution-- Suggestion --
The code of interest is this one: https://github.com/dotnet/aspnetcore/blob/main/src/OpenApi/src/Extensions/OpenApiEndpointRouteBuilderExtensions.cs#L57
Here an
Utf8BufferTextWriteris retrieved, and it in turn inherits fromTextWriter.TextWriteroffers a constructor that takes anIFormatProvider, butUtf8BufferTextWriterimplicitly calls the default constructor instead which does not set anIFormatProvider, and the default ofCultureInfo.CurrentCultureis used