omerkocadere
## Summary When using ASP.NET Core's built-in OpenAPI generator (`Microsoft.AspNetCore.OpenApi`) with .NET 10, `IFormFile` parameters no longer generate the correct `FileParameter` TypeScript type in the NSwag client. The generated client either emits broken code or silently drops the file from the request. ## Root Cause .NET 10 defaults to **OpenAPI 3.1** output (see [aspnetcore release notes](https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0?view=aspnetcore-10.0#openapi)). Under 3.1 / JSON Schema 2020-12, `.NET's` OpenAPI generator emits `IFormFile` as an **empty object component schema** (`{ type: object, properties: {} }`) instead of `{ type: string, format: binary }`. NSwag's TypeScript generator fails in two places: 1. **Schema level** – it doesn't recognize `IFormFile` as a binary type, so it never emits `FileParameter` for the parameter. 2. **Inline vs. $ref** – even when the component schema is manually patched to `{ type: string, format: binary }`, NSwag only recognizes a file upload when the `format: binary` property is **inlined** in the request body. A `$ref` pointing to a binary component schema is not recognized as a file, so `FormData.append()` is never generated. ## Steps to Reproduce 1. Create an ASP.NET Core 10 Minimal API with a file upload endpoint: ```csharp app.MapPost("/upload", ([FromForm] IFormFile file) => Results.Ok()) .DisableAntiforgery(); ``` 2. Use `Microsoft.AspNetCore.OpenApi` (default settings → OpenAPI 3.1). 3. Run NSwag to generate a TypeScript Angular client. **Expected:** The generated method has a `file: FileParameter` parameter and calls `FormData.append("file", file.data, file.fileName)`. **Actual:** The parameter is missing or typed as `any`, and `FormData.append` is never called — the file is silently dropped from the request. ## Current Workaround Two schema/document transformers are required to patch the generated OpenAPI document before NSwag reads it: ```csharp // 1. Rewrite the IFormFile component schema to { type: string, format: binary } options.AddSchemaTransformer(static (schema, context, _) => { if (context.JsonTypeInfo.Type != typeof(IFormFile)) return Task.CompletedTask; schema.Type = JsonSchemaType.String; schema.Format = "binary"; schema.Properties?.Clear(); schema.Required?.Clear(); return Task.CompletedTask; }); // 2. Inline the binary schema into multipart request bodies // (NSwag requires inline format:binary, $ref is not recognized) options.AddDocumentTransformer(static (document, _, _) => { var requestSchemas = from pathItem in document.Paths.Values from operation in pathItem.Operations?.Values ?? Enumerable.Empty<OpenApiOperation>() from mediaType in operation.RequestBody?.Content?.Values ?? Enumerable.Empty<OpenApiMediaType>() let properties = mediaType.Schema?.Properties where properties is not null select properties; foreach (var properties in requestSchemas) foreach (var key in properties.Keys.ToList()) if (properties[key].Format == "binary") properties[key] = new OpenApiSchema { Type = JsonSchemaType.String, Format = "binary" }; return Task.CompletedTask; }); ``` This should not be necessary — NSwag should handle this natively. ## Expected Fix NSwag's TypeScript client generator should: 1. Recognize `IFormFile` (or any schema component with `format: binary`) as a file parameter and emit `FileParameter`. 2. Handle `$ref` to a binary component schema correctly — treat it as a file upload, not an object. This is related to NJsonSchema's partial OpenAPI 3.1 / JSON Schema 2020-12 support ([NJsonSchema#1603](https://github.com/RicoSuter/NJsonSchema/issues/1603)). ## Environment - NSwag: 14.x - .NET: 10.0 - `Microsoft.AspNetCore.OpenApi`: 10.0 (default OpenAPI version: 3.1) - NJsonSchema: 11.x - Generated client: TypeScript / Angular ## Related - [NJsonSchema#1603](https://github.com/RicoSuter/NJsonSchema/issues/1603) — OpenAPI 3.1 / JSON Schema 2020-12 support - [dotnet/aspnetcore#65017](https://github.com/dotnet/aspnetcore/issues/65017) — .NET 10 emits IFormFile as empty object schema