Skip to content

MapOpenApi writes invalid json if example contains OpenApiDouble and CurrentCulture formats doubles with comma #60628

Open
@park-jasper

Description

@park-jasper

Is there an existing issue for this?

  • I have searched the existing issues

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions