Skip to content

Commit

Permalink
Fix for multipart/formdata schema bug. (#4476)
Browse files Browse the repository at this point in the history
Fixes #3524 and #4392
  • Loading branch information
bobend committed Oct 2, 2023
1 parent b32ccee commit 340dc3a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 2 deletions.
126 changes: 126 additions & 0 deletions src/NSwag.CodeGeneration.CSharp.Tests/BinaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace NSwag.CodeGeneration.CSharp.Tests
{
public class BinaryTests
{

[Fact]
public async Task When_body_is_binary_then_stream_is_used_as_parameter_in_CSharp()
{
Expand Down Expand Up @@ -381,6 +382,131 @@ public async Task WhenSpecContainsFormDataInNestedMultipartForm_ThenFormDataIsUs
Assert.Contains("class FileParameter", code);
Assert.Contains("content_.Add(content_contents_, \"Contents\", contents.FileName ?? \"Contents\");", code);
}
[Fact]
public async Task When_multipart_with_ref_should_read_schema()
{
var yaml = @"openapi: 3.0.0
servers:
- url: https://www.example.com/
info:
version: '2.0.0'
title: 'Test API'
paths:
/files:
post:
tags:
- Files
summary: 'Add File'
operationId: addFile
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAddFileResponse'
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/CreateAddFileRequest'
components:
schemas:
CreateAddFileResponse:
type: object
required:
- fileId
properties:
fileId:
type: string
format: uuid
CreateAddFileRequest:
type: object
additionalProperties: false
properties:
file:
type: string
format: binary
model:
type: string
enum: ['model-1']
required:
- file
- model";

var document = await OpenApiYamlDocument.FromYamlAsync(yaml);

// Act
var codeGenerator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings());
var code = codeGenerator.GenerateFile();

//// Assert
Assert.Contains("public virtual async System.Threading.Tasks.Task<CreateAddFileResponse> AddFileAsync(FileParameter file, Model? model, System.Threading.CancellationToken cancellationToken)", code);
Assert.Contains("var content_file_ = new System.Net.Http.StreamContent(file.Data);", code);
Assert.Contains("public partial class FileParameter", code);
}
[Fact]
public async Task When_multipart_inline_schema()
{
var yaml = @"openapi: 3.0.0
servers:
- url: https://www.example.com/
info:
version: '2.0.0'
title: 'Test API'
paths:
/files:
post:
tags:
- Files
summary: 'Add File'
operationId: addFile
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAddFileResponse'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: false
properties:
file:
type: string
format: binary
model:
type: string
enum: ['model-1']
required:
- file
- model
components:
schemas:
CreateAddFileResponse:
type: object
required:
- fileId
properties:
fileId:
type: string
format: uuid";

var document = await OpenApiYamlDocument.FromYamlAsync(yaml);

// Act
var codeGenerator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings());
var code = codeGenerator.GenerateFile();

//// Assert
Assert.Contains("public virtual async System.Threading.Tasks.Task<CreateAddFileResponse> AddFileAsync(FileParameter file, Model? model, System.Threading.CancellationToken cancellationToken)", code);
Assert.Contains("var content_file_ = new System.Net.Http.StreamContent(file.Data);", code);
Assert.Contains("public partial class FileParameter", code);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public CSharpFileTemplateModel(
_settings.CSharpGeneratorSettings.ExcludedTypeNames?.Contains("FileParameter") != true &&
(_document.Operations.Any(o => o.Operation.ActualParameters.Any(p => p.ActualTypeSchema.IsBinary)) ||
_document.Operations.Any(o => o.Operation?.RequestBody?.Content?.Any(c => c.Value.Schema?.IsBinary == true ||
c.Value.Schema?.ActualProperties.Any(p => p.Value.IsBinary ||
c.Value.Schema?.ActualSchema.ActualProperties.Any(p => p.Value.IsBinary ||
p.Value.Item?.IsBinary == true ||
p.Value.Items.Any(i => i.IsBinary)
) == true) == true));
Expand Down
2 changes: 1 addition & 1 deletion src/NSwag.CodeGeneration/Models/OperationModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ protected IList<OpenApiParameter> GetActualParameters()

var formDataSchema =
_operation?.RequestBody?.Content?.ContainsKey("multipart/form-data") == true ?
_operation.RequestBody.Content["multipart/form-data"]?.Schema : null;
_operation.RequestBody.Content["multipart/form-data"]?.Schema.ActualSchema: null;

if (formDataSchema != null && formDataSchema.ActualProperties.Count > 0)
{
Expand Down

0 comments on commit 340dc3a

Please sign in to comment.