Skip to content

Built-in OpenAPI generator emits 3.0-era format: binary for binary/file types in 3.1/3.2 documents #67826

Description

@danroth27

Is there an existing issue for this?

  • I have searched the existing issues

Summary

Microsoft.AspNetCore.OpenApi now defaults OpenApiOptions.OpenApiVersion to OpenApi3_2, but the generator describes binary/file types using the OpenAPI 3.0-era idiom type: string, format: binary — including when it produces 3.1 and 3.2 documents, where that representation is no longer part of the specification.

The same 3.0 shape is emitted verbatim regardless of the target document version (verified with the repro below on 11.0.100-preview.6).

Repro

BinaryFormatRepro.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net11.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="11.0.0-preview.6.*" />
  </ItemGroup>
</Project>

Program.cs:

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.OpenApi;

var builder = WebApplication.CreateBuilder(args);

// Three documents that differ ONLY by target spec version.
builder.Services.AddOpenApi("v3_0", o => o.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0);
builder.Services.AddOpenApi("v3_1", o => o.OpenApiVersion = OpenApiSpecVersion.OpenApi3_1);
builder.Services.AddOpenApi("v3_2", o => o.OpenApiVersion = OpenApiSpecVersion.OpenApi3_2); // current default

var app = builder.Build();
app.MapOpenApi("/openapi/{documentName}.json");

// Binary response (file download)
app.MapGet("/download", () => Results.File(new byte[] { 1, 2, 3 }, "application/octet-stream"))
   .Produces<FileContentHttpResult>(StatusCodes.Status200OK, "application/octet-stream");

// Binary request (file upload)
app.MapPost("/upload", (IFormFile file) => Results.Ok());

app.Run();

Run it, then fetch the three documents:

curl http://localhost:5199/openapi/v3_0.json
curl http://localhost:5199/openapi/v3_1.json
curl http://localhost:5199/openapi/v3_2.json

Actual behavior

The documents correctly declare different versions ("openapi": "3.0.4", "3.1.2", "3.2.0"), but the binary schema is identical in all three:

// components.schemas in v3_0.json, v3_1.json AND v3_2.json — byte-for-byte identical:
"FileContentHttpResult": { "type": "string", "format": "binary" },
"IFormFile":             { "type": "string", "format": "binary" }

Expected behavior

When generating a 3.1 or 3.2 document, binary data should use the JSON-Schema-2020-12–aligned representation rather than format: binary:

  • Raw bytes: describe via the media type / contentMediaType (the schema can be omitted when the media type already conveys binary).
  • Base64-in-JSON: contentEncoding: base64 (this is the correct target for byte[], and is distinct from raw-binary).

Specification references

Note: format: binary is not invalid under 3.1/3.2 (format is an open annotation), but it is the deprecated 3.0 idiom and not the representation the spec prescribes, so tooling that follows 3.1+ may not interpret it as binary.

Scope

Affects all special-cased binary types in src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs:

  • IFormFile, IFormFileCollection
  • Stream, PipeReader
  • FileContentResult, FileStreamResult
  • FileContentHttpResult, FileStreamHttpResult

Notes

.NET Version

11.0.100-preview.6.26315.102 (main)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

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

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions