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

Element defined as type = "string", format = "binary" gets passed always as the last element in a multipart/form-data? #6979

Closed
kikaragyozov opened this issue Feb 22, 2021 · 2 comments · Fixed by #7008

Comments

@kikaragyozov
Copy link

Q&A (please complete the following information)

  • OS: Windows 10
  • Browser: Chrome
  • Version: N/A
  • Method of installation: Via the usage of Swashbuckle.AspNetCore
  • Swagger-UI version: 3.42.0
  • Swagger/OpenAPI version: Swagger 3.0, OpenAPI 3.0

As per OpenAPI 3.0 specifications, there is no longer a type "file", but instead, we should define files using the type string and a format either binary, or byte. (Source: https://swagger.io/docs/specification/data-models/data-types/)

When we define a multipart/form-data content, which includes several properties, one of which is a file, if that file is defined in any order, using the legacy 2.0 approach - it gets fed in the order of which it was defined when reading the underlying form data stream. (expected result)

But when it is defined in the new 3.0 convention, for some reason, the data to the server is passed in a way that it is always the last element in the multipart/form-data, regardless in what order the file was defined.

Meaning if we had a single file, and 3 other properties of any other type,, the file would always be the last one to be read in the multipart/form-data request.

Is this a feature? If so, why the subtle differences?

@mathis-m
Copy link
Contributor

Minimal Reproduction YAML:
https://editor.swagger.io/?url=https://gist.githubusercontent.com/mathis-m/fcb6d61ab4c3c8fab13bbeff01a0d335/raw/8ccc871c36ec218b8a9076ad65dab0350db8fd95/8Fyc7Z0ykv.txt

openapi: 3.0.3
info:
  title: asd
  version: 0.0.1
paths:
  /test:
    post:
      requestBody:
        content:
          multipart/form-data:
            schema: 
              $ref: '#/components/schemas/TestBody'
      responses:
        200:
          description: ok
components:
  schemas:
    TestBody:
      type: object
      properties:
        one:
          type: number
          example: 1
        two:
          type: string
          format: binary
        three:
          type: string
          example: 3

@mathis-m
Copy link
Contributor

mathis-m commented Feb 27, 2021

I finally traced this down to 640f70d#diff-298732647ce460b7a2a4efd771fa598c8c6c583029c82d29364cefeff0772154R88 where it was introduced with #4592 in v3.16.0.

Background:
when providing type string format binary aka file position is not preserved,
because it is not registered on component mount like all others do.
So the state is later on corrupted,
because when the file is set and so a new property will be added to requestData Map in state.
This results in beeing the last property. since all other properties components are registering their value on component mount the oder is preserved for those.

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

Successfully merging a pull request may close this issue.

3 participants