Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple file upload via UI #1421

Open
Fedorus opened this issue Jun 27, 2018 · 19 comments
Open

Multiple file upload via UI #1421

Fedorus opened this issue Jun 27, 2018 · 19 comments

Comments

@Fedorus
Copy link

Fedorus commented Jun 27, 2018

Is there a way to send multiple files in one request using:

app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, settings =>{
			   settings.UseJsonEditor = true;
			});

first of all it allows selection of only 1 file.
And after that in file: NSwag.AspNet.Owin/SwaggerUi/swagger-ui.js it just doesn`t add files:

      if (o.type === 'file') {
        map[o.name] = o.files[0];
      }
@RicoSuter
Copy link
Owner

Seems to be a problem with swagger ui and not nswag. Did you try SwaggerUi3? Is the generated swagger spec correct? Where did you find the last code snippet?

@Fedorus
Copy link
Author

Fedorus commented Jun 28, 2018

Where did you find the last code snippet?

link

Is the generated swagger spec correct?

Yes, spec is correct.

Did you try SwaggerUi3?

Hm, I`ll look on it today, thanks.

@Fedorus
Copy link
Author

Fedorus commented Jun 28, 2018

Same thing with 3rd version. HTTP side doesn`t use "multiple" atribute and if you add it will still send only first file.
The generated side looks good:

{ "type": "file", "name": "files", "in": "formData", "collectionFormat": "multi", "x-nullable": true, "items": { "type": "file" }

@RicoSuter
Copy link
Owner

Maybe you should check with the Swagger UI 3 guys whether this is supported and correct Swagger spec?

https://github.com/swagger-api/swagger-ui

@BramMusters
Copy link

BramMusters commented Jul 6, 2018

Yes there is, the following shows a file upload for me, in both Swagger UI 2 and 3 :

public async Task<List<X>> X([FromForm] IFormFile file1, [FromForm] IFormFile file2)
{
            file1 = this.HttpContext.Request.Form.Files[0];
            file2 = this.HttpContext.Request.Form.Files[1];

For some reason the files are not bound correctly by ASP.NET Core, so that's why I get it manually from the request's context.

Which brings me to the following problem: The above approach only works for app.UserSwaggerUi(3), if I'm using the new ApiExplorer approach, the file upload is not recognized, as can be seen in the following screencap:
capture

@ranouf
Copy link

ranouf commented Sep 25, 2018

Hi,

I try to transfer an array of IFile from Angular to .Net Core.
It seems that I have the same issue. my variable [FromForm] has all properties to null.

Did you find a way to bind it automatically?

here is my Dto

Server:

    public class SampleDto
    {
        public Guid Id{ get; set; }
        public string Text { get; set; }
        public IEnumerable<string> ImageUrl { get; set; }
        public IEnumerable<IFormFile> Image { get; set; }
    }

        [HttpPut]
        [Route("{id:guid}")]
        public async Task<IActionResult> UpdateAsync([FromRoute]Guid id, [FromForm] SampleDto dto)
        {
           Console.WriteLine(dto.Text); //Return null
           Console.WriteLine(dto.Image[0]?.FileName); //Return null

            return Ok();
        }

Here is the value of my Form
image

Here is what the browser send:
image

Here is the code generated by nswag:

update(id: string, dto: SampleDto | null | undefined): Observable<SampleDto | null> {
     let url_ = this.baseUrl + "/api/v1/Sample/{id}";
     if (id === undefined || id === null)
         throw new Error("The parameter 'id' must be defined.");
     url_ = url_.replace("{id}", encodeURIComponent("" + id)); 
     url_ = url_.replace(/[?&]$/, "");

     const content_ = new FormData();
     if (dto !== null && dto !== undefined)
         content_.append("dto", dto.toString());

     let options_ : any = {
         body: content_,
         observe: "response",
         responseType: "blob",
         headers: new HttpHeaders({
             "Accept": "application/json"
         })
     };

     return _observableFrom(this.transformOptions(options_)).pipe(_observableMergeMap(transformedOptions_ => {
         return this.http.request("put", url_, transformedOptions_);
     })).pipe(_observableMergeMap((response_: any) => {
         return this.transformResult(url_, response_, (r) => this.processUpdate(<any>r));
     })).pipe(_observableCatch((response_: any) => {
         if (response_ instanceof HttpResponseBase) {
             try {
                 return this.transformResult(url_, response_, (r) => this.processUpdate(<any>r));
             } catch (e) {
                 return <Observable<SampleDto | null>><any>_observableThrow(e);
             }
         } else
             return <Observable<SampleDto | null>><any>_observableThrow(response_);
     }));
 }

Here there is a repo where it s possible to upload data and File: https://github.com/fiyazbinhasan/AngularSpaCore

In Swagger, the array of IFormFile seems to be manage correctly now:

image

@zuckerthoben
Copy link

I have the same problem as @barmyard. With ApiExplorer my Upload Actions are not detected correctly. Any updates?

@MennoVisser91
Copy link

I have the same problem. Any updates???

@JonasDev17
Copy link

This is actually a swagger-ui issue. Go vote for it by giving a thumbs up: swagger-api/swagger-ui#4600

@RicoSuter
Copy link
Owner

So the generated spec is correct and we have to wait for a swagger ui update?

@Fedorus
Copy link
Author

Fedorus commented Jan 21, 2020

I`m shoked that this bug is still exist,,,

@JonasDev17
Copy link

So the generated spec is correct and we have to wait for a swagger ui update?

I think so, yes...

@Juice-XIJ
Copy link

Juice-XIJ commented Jun 4, 2020

Hi @RicoSuter at this moment the swagger issue just fixed a few days ago.

I updated NSwag to 13.6.0. Now the generated swagger.json looks like:

"requestBody": {
    "content": {
        "multipart/form-data": {
            "schema": {
                "type": "object",
                "properties": {
                    "audioFileList": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "format": "binary"
                        }
                    }
                }
            }
        }
    }
}

This schema is the same as latest swagger client. However when I use the swagger ui to send request to the sever, I found that the request is like:

Host: localhost:8446
Connection: keep-alive
Content-Length: 157
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37
Ocp-Apim-Subscription-Key: 5b9e48e85daf4c32aab4d403d0eea5cd
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryplFirfy6HmAbgpAl
Origin: https://localhost:8446
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://localhost:8446/UI/index.html?urls.primaryName=OpenApi%203.0
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: ai_user=I8/5h|2020-04-18T00:44:53.179Z; grafana_session=348d3dc50bd60b4c0045046d35440dc9

------WebKitFormBoundaryplFirfy6HmAbgpAl
Content-Disposition: form-data; name="audioFileList"

[object File]
------WebKitFormBoundaryplFirfy6HmAbgpAl--

The request only sent string '[object file]" instead of the form data that I selected (also, content length is only 157).

Hence, any thoughts about it? Thanks!

@dmitry-pavlov
Copy link

dmitry-pavlov commented Aug 29, 2020

I confirm that:

  • Swagger UI 3 sends files array as [object File] <-- which makes ASP.NET Core request.Form.Files getting no files on controller side.
curl -X POST "http://localhost:5000/api/attachments" -H "accept: application/json" -H "Authorization: Bearer eyJ...trimmed..." 
-H "Content-Type: multipart/form-data" -F "StructureId=14" -F "Description=dsgf" -F "Files=[object File]" 
  • Open API schema looks good and generates correct TypeScript code (the only thing I had to adjust was mapping form files to to objects of FileParameter - code snippet is below as well) which works fine.
"/api/attachments": {
      "post": {
        "tags": [           "Attachments"         ],
        "operationId": "Attachments_AttachStructureFile",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "StructureId": {                     "type": "integer",                    "format": "int32"                  },
                  "Description": {                    "type": "string",                    "nullable": true                  },
                  "Files": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  },
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "", 
            "content": {
              "application/json": {
                "schema": {                  "$ref": "#/components/schemas/SipAttachStructureFileResponse"                }
              }
            }
          }
        },
        "security": [          {            "JWT": []          }        ]
      }
    }

What I use:

  • NSwag.AspNetCore v 13.7.0 (package in API project which is used to generate OpenAPI spec for Swagger UI 3)
  • NSwagStudio (x64) 13.7.0.0 (this what I use to generate TS client)

So it's fine except using Swagger UI 3 for uploading files. Any workarounds how to make Swagger UI sending correct data?

@RicoSuter
Copy link
Owner

Do we need to update Swagger UI 3 in NSwag.AspNetCore?
Didnt do that for some months so maybe there are already improvements.

@Spaeda
Copy link

Spaeda commented Oct 5, 2021

Hi,

Any news about this point?

I try with Swashbuckle and UI manage multi files
image

@kodiKING10
Copy link

kodiKING10 commented Jan 5, 2022

Different from Swashbuckle, NSwag still can't handle multiple files, this is the issue opened in swashbuckle domaindrivendev/Swashbuckle.AspNetCore#1029, this needs to be fixed asap.

@mm3141
Copy link

mm3141 commented Apr 25, 2022

Do we need to update Swagger UI 3 in NSwag.AspNetCore? Didnt do that for some months so maybe there are already improvements.

Looks like it has been fixed here: https://github.com/swagger-api/swagger-ui/releases/tag/v3.26.0

@n0one42
Copy link

n0one42 commented Feb 23, 2024

I also have still the same problem.
public async Task<IResult> MyPostCall(HttpRequest request, ISender sender, [FromForm] List<IFormFile> files)
I have to use [FromForm] List<IFormFile> to get the Choose File Button. Otherwise it does not appear but files remains empty while the request.Form.Files contains the uploaded files.

I also tried IFormFileCollection but this also does not work.

My only solution to get the Choose File button is to implement the not filled List and handling the request.Form.Files

files = request.Form.Files.ToList();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests