From 1d98f023bf171ea998c53b7e2bcb997692af535b Mon Sep 17 00:00:00 2001 From: Marco Minerva Date: Tue, 2 Sep 2025 12:34:33 +0200 Subject: [PATCH] Add support for FileContentResult in OpenAPI schemas Updated OpenApiSchemaService to handle FileContentResult, ensuring schemas are generated as `string` with `binary` format. Introduced a new test in OpenApiSchemaServiceTests to validate OpenAPI response handling for FileContentResult, ensuring correct schema and content type representation. --- .../Services/Schemas/OpenApiSchemaService.cs | 4 ++-- .../Extensions/JsonTypeInfoExtensionsTests.cs | 1 + .../OpenApiSchemaService.ResponseSchemas.cs | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs b/src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs index 12b0c1ed996c..69aac63f2f37 100644 --- a/src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs +++ b/src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs @@ -58,9 +58,9 @@ internal sealed class OpenApiSchemaService( TransformSchemaNode = (context, schema) => { var type = context.TypeInfo.Type; - // Fix up schemas generated for IFormFile, IFormFileCollection, Stream, and PipeReader + // Fix up schemas generated for IFormFile, IFormFileCollection, Stream, PipeReader and FileContentResult // that appear as properties within complex types. - if (type == typeof(IFormFile) || type == typeof(Stream) || type == typeof(PipeReader)) + if (type == typeof(IFormFile) || type == typeof(Stream) || type == typeof(PipeReader) || type == typeof(Mvc.FileContentResult)) { schema = new JsonObject { diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Extensions/JsonTypeInfoExtensionsTests.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Extensions/JsonTypeInfoExtensionsTests.cs index a402ef393a59..a9ae3255708b 100644 --- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Extensions/JsonTypeInfoExtensionsTests.cs +++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Extensions/JsonTypeInfoExtensionsTests.cs @@ -63,6 +63,7 @@ public class Baz [typeof(JsonPatchDocument), "JsonPatchDocument"], [typeof(Stream), "Stream"], [typeof(PipeReader), "PipeReader"], + [typeof(FileContentResult), "FileContentResult"], [typeof(Results, Ok>), "ResultsOfOkOfTodoWithDueDateAndOkOfTodo"], [typeof(Ok), "OkOfTodo"], [typeof(NotFound), "NotFoundOfTodoWithDueDate"], diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ResponseSchemas.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ResponseSchemas.cs index c0a38a43997b..05aaeb956848 100644 --- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ResponseSchemas.cs +++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ResponseSchemas.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Net.Http; +using System.Net.Mime; using System.Text.Json.Nodes; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; @@ -1031,6 +1032,29 @@ await VerifyOpenApiDocument(actionDescriptor, document => }); } + [Fact] + public async Task GetOpenApiResponse_HandlesFileContentResultTypeResponse() + { + // Arrange + var builder = CreateBuilder(); + + // Act + builder.MapPost("/filecontentresult", () => { return new FileContentResult([], MediaTypeNames.Application.Octet); }) + .Produces(contentType: MediaTypeNames.Application.Octet); + + // Assert + await VerifyOpenApiDocument(builder, document => + { + var operation = document.Paths["/filecontentresult"].Operations[HttpMethod.Post]; + var responses = Assert.Single(operation.Responses); + var response = responses.Value; + Assert.True(response.Content.TryGetValue("application/octet-stream", out var mediaType)); + var schema = mediaType.Schema; + Assert.Equal(JsonSchemaType.String, schema.Type); + Assert.Equal("binary", schema.Format); + }); + } + [ApiController] [Produces("application/json")] public class TestController