Post API method with IFormFile parameter generate 400 BadRequest with new ApiControllerAttribute.
Works if I remove attribute or I disable InferBindingSourcesForParameters with
cs
services.Configure<ApiBehaviorOptions>(options => { options.SuppressInferBindingSourcesForParameters = true; });
Tested with SwaggerUI and TypeScript generated client. Same error.
API method:
cs
[HttpPost]
public IActionResult Update(IFormFile file)
{
return NoContent();
}
Have you tried with the new API Explorer based generator?
Sorry for the delay. I tried with API Explorer based generator with InferBindingSourcesForParameters. This generates this TypeScript:
ts
updateLogo(file: FileParameter | null): Observable<void> {
...
}
But the FileParameter type is not declared in the generated file.
My nswag.json (v11.18.7.0):
json
{
"runtime": "NetCore21",
"defaultVariables": null,
"swaggerGenerator": {
"aspNetCoreToSwagger": {
"project": "MyProject.csproj",
"msBuildProjectExtensionsPath": null,
"configuration": null,
"runtime": null,
"targetFramework": "netcoreapp2.1",
"noBuild": true,
"verbose": true,
"workingDirectory": null,
"defaultPropertyNameHandling": "CamelCase",
"defaultReferenceTypeNullHandling": "Null",
"defaultEnumHandling": "CamelCaseString",
"flattenInheritanceHierarchy": false,
"generateKnownTypes": true,
"generateXmlObjects": false,
"generateAbstractProperties": false,
"ignoreObsoleteProperties": true,
"allowReferencesWithProperties": false,
"excludedTypeNames": [],
"serviceHost": null,
"serviceBasePath": null,
"serviceSchemes": [],
"infoTitle": "",
"infoDescription": null,
"infoVersion": "",
"includedVersions": null,
"documentTemplate": null,
"documentProcessorTypes": [],
"operationProcessorTypes": [],
"typeNameGeneratorType": null,
"schemaNameGeneratorType": null,
"contractResolverType": null,
"serializerSettingsType": null,
"output": "Clients/swagger.json",
"outputType": "Swagger2",
"assemblyPaths": [],
"assemblyConfig": null,
"referencePaths": []
}
},
"codeGenerators": {
"swaggerToTypeScriptClient": {
"className": "{controller}Client",
"moduleName": "",
"namespace": "",
"typeScriptVersion": 2.7,
"template": "Angular",
"promiseType": "Promise",
"httpClass": "HttpClient",
"useSingletonProvider": true,
"injectionTokenType": "InjectionToken",
"rxJsVersion": 6.0,
"dateTimeType": "Date",
"nullValue": "Null",
"generateClientClasses": true,
"generateClientInterfaces": false,
"generateOptionalParameters": false,
"exportTypes": true,
"wrapDtoExceptions": false,
"clientBaseClass": null,
"wrapResponses": false,
"wrapResponseMethods": [],
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"protectedMethods": [],
"configurationClass": null,
"useTransformOptionsMethod": false,
"useTransformResultMethod": false,
"generateDtoTypes": true,
"operationGenerationMode": "MultipleClientsFromOperationId",
"markOptionalProperties": true,
"generateCloneMethod": false,
"typeStyle": "Interface",
"classTypes": [],
"extendedClasses": [],
"extensionCode": null,
"generateDefaultValues": true,
"excludedTypeNames": [],
"handleReferences": false,
"generateConstructorInterface": true,
"convertConstructorInterfaceData": false,
"importRequiredTypes": true,
"useGetBaseUrlMethod": false,
"baseUrlTokenName": "API_BASE_URL",
"queryNullValue": "",
"templateDirectory": null,
"typeNameGeneratorType": null,
"propertyNameGeneratorType": null,
"enumNameGeneratorType": null,
"serviceHost": null,
"serviceSchemes": null,
"output": "Clients/api.client.ts"
}
}
}
Comparison of the generated swagger.
With webApiToSwagger:
json
"put": {
"operationId": "UpdateLogo",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true,
"description": "Id",
"format": "int32",
"x-nullable": false
},
{
"type": "file",
"name": "logo",
"in": "formData",
"required": true,
"description": "Logo file",
"x-nullable": true
}
]
With swaggerGenerator:
json
"put": {
"operationId": "UpdateLogo",
"consumes": [
"application/json-patch+json",
"application/json",
"text/json",
"application/*+json"
],
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true,
"description": "id",
"format": "int32",
"x-nullable": false
},
{
"name": "logo",
"in": "body",
"required": true,
"schema": {
"type": "file"
},
"description": "Logo file",
"x-nullable": true
}
]
I think it's the absence of "multipart/form-data" consumes. I tried to add the attribute in method of controller but no effect.
@pranavkm can you have a look this?
Possible same issue https://github.com/RSuter/NSwag/issues/1550
@YZahringer do you have the compat version set to 2.1? https://docs.microsoft.com/en-us/aspnet/core/migration/20_21?view=aspnetcore-2.1#changes-to-startup has a sample.
@pranavkm It works with compat version 2.1, thanks 馃憤
It would be convenient to mention it in the documentation of NSwag.
@YZahringer can you update the wiki? I think this is the best place for that: https://github.com/RSuter/NSwag/wiki/AspNetCoreToSwaggerGenerator
@RSuter