Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/NSwag.CodeGeneration.CSharp.Tests/BinaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,64 @@ public async Task When_body_is_binary_then_stream_is_used_as_parameter_in_CSharp
CSharpCompiler.AssertCompile(code);
}

[Fact]
public async Task When_body_is_binary_then_IFormFile_is_used_as_part_of_object_in_CSharp_ASPNETCore()
{
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: 'something'
content:
application/json:
schema:
$ref: '#/components/schemas/FileToken'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
name:
type: string
components:
schemas:
FileToken:
type: object
required:
- fileId
properties:
fileId:
type: string
format: uuid";

var document = await OpenApiYamlDocument.FromYamlAsync(yaml);

// Act
CSharpControllerGeneratorSettings settings = new CSharpControllerGeneratorSettings();
settings.ControllerTarget = CSharpControllerTarget.AspNetCore;
var codeGenerator = new CSharpControllerGenerator(document, settings);
var code = codeGenerator.GenerateFile();

// Assert
await VerifyHelper.Verify(code);
CSharpCompiler.AssertCompile(code);
}

[Fact]
public async Task When_body_is_binary_then_IFormFile_is_used_as_parameter_in_CSharp_ASPNETCore()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@


namespace MyNamespace
{
using System = global::System;

public interface IController
{




System.Threading.Tasks.Task<FileToken> AddFileAsync(Microsoft.AspNetCore.Http.IFormFile file, string name);

}


public partial class Controller : Microsoft.AspNetCore.Mvc.ControllerBase
{
private IController _implementation;

public Controller(IController implementation)
{
_implementation = implementation;
}

[Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("files")]
public System.Threading.Tasks.Task<FileToken> AddFile(Microsoft.AspNetCore.Http.IFormFile file, string name)
{

return _implementation.AddFileAsync(file, name);
}

}

public partial class FileToken
{

[Newtonsoft.Json.JsonProperty("fileId", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public System.Guid FileId { get; set; }

private System.Collections.Generic.IDictionary<string, object> _additionalProperties;

[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>()); }
set { _additionalProperties = value; }
}

}

public partial class FileParameter
{
public FileParameter(System.IO.Stream data)
: this (data, null, null)
{
}

public FileParameter(System.IO.Stream data, string fileName)
: this (data, fileName, null)
{
}

public FileParameter(System.IO.Stream data, string fileName, string contentType)
{
Data = data;
FileName = fileName;
ContentType = contentType;
}

public System.IO.Stream Data { get; private set; }

public string FileName { get; private set; }

public string ContentType { get; private set; }
}


}
48 changes: 31 additions & 17 deletions src/NSwag.CodeGeneration.CSharp/Models/CSharpOperationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,43 +264,57 @@ protected override string ResolveParameterType(OpenApiParameter parameter)
{
if (schema.Type == JsonObjectType.Array && schema.Item.IsBinary)
{
return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
"System.Collections.Generic.ICollection<Microsoft.AspNetCore.Http.IFormFile>" :
"System.Collections.Generic.ICollection<System.Web.HttpPostedFileBase>";
return ResolveControllerBinaryCollectionType(controllerSettings);
}
else
{
return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
"Microsoft.AspNetCore.Http.IFormFile" :
"System.Web.HttpPostedFileBase";
}
}
else
{
return parameter.HasBinaryBodyWithMultipleMimeTypes ? "FileParameter" : "System.IO.Stream";

return ResolveControllerBinarySingleType(controllerSettings);
}

return parameter.HasBinaryBodyWithMultipleMimeTypes ? "FileParameter" : "System.IO.Stream";
}

if (schema.Type == JsonObjectType.Array && (schema.Item?.IsBinary ?? false))
{
return "System.Collections.Generic.IEnumerable<FileParameter>";
return _settings is CSharpControllerGeneratorSettings controllerSettings
? ResolveControllerBinaryCollectionType(controllerSettings)
: "System.Collections.Generic.IEnumerable<FileParameter>";
}

if (schema.IsBinary)
{
if (parameter.CollectionFormat == OpenApiParameterCollectionFormat.Multi && !schema.Type.HasFlag(JsonObjectType.Array))
{
return "System.Collections.Generic.IEnumerable<FileParameter>";
return _settings is CSharpControllerGeneratorSettings controllerSettings
? ResolveControllerBinaryCollectionType(controllerSettings)
: "System.Collections.Generic.IEnumerable<FileParameter>";
}
else
{
return _settings is CSharpControllerGeneratorSettings controllerSettings
? ResolveControllerBinarySingleType(controllerSettings)
: "FileParameter";
}

return "FileParameter";
}

return base.ResolveParameterType(parameter)
.Replace(_settings.CSharpGeneratorSettings.ArrayType + "<", _settings.ParameterArrayType + "<")
.Replace(_settings.CSharpGeneratorSettings.DictionaryType + "<", _settings.ParameterDictionaryType + "<");
}

private static string ResolveControllerBinarySingleType(CSharpControllerGeneratorSettings controllerSettings)
{
return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
"Microsoft.AspNetCore.Http.IFormFile" :
"System.Web.HttpPostedFileBase";
}

private static string ResolveControllerBinaryCollectionType(CSharpControllerGeneratorSettings controllerSettings)
{
return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
"System.Collections.Generic.ICollection<Microsoft.AspNetCore.Http.IFormFile>" :
"System.Collections.Generic.ICollection<System.Web.HttpPostedFileBase>";
}

/// <summary>Creates the response model.</summary>
/// <param name="operation">The operation.</param>
/// <param name="statusCode">The status code.</param>
Expand Down
Loading