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

multipartfile/ type: string, format: binary not always handled correctly #50

Open
NANASHI0X74 opened this issue Jun 15, 2021 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@NANASHI0X74
Copy link
Contributor

NANASHI0X74 commented Jun 15, 2021

I see that the project is supposed to support file uploads via multipartfile content, but it doesn't seem to always work. Maybe the problem is it only works with inline schemas and not referenced schemas?

Example:

schema
paths:
  /documents/:
    post:
      operationId: documents_create
      description: ''
      tags:
      - documents
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DocumentEditRequest'
      security:
      - tokenauth: []
      - cookieAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentEdit'
          description: ''
components:
  schemas:
    DocumentEditRequest:
      type: object
      properties:
        creator:
          type: integer
          nullable: true
        company:
          type: integer
          nullable: true
        name:
          type: string
          maxLength: 255
        description:
          type: string
          nullable: true
          maxLength: 255
        filepath:
          type: string
          format: binary
          nullable: true
generated model
part of openapi.api;

// This file is generated by https://github.com/dart-ogurets/dart-openapi-maven - you should not modify it
// log generation bugs on Github, as part of the license, you must not remove these headers from the Mustache templates.

// DocumentEditRequest
class DocumentEditRequest {
    
      int? creator;
    
      int? company;
    
      String? name;
    
      String? description;
    
      ApiResponse? filepath;
DocumentEditRequest({ this.creator,
    this.company,
    this.name,
    this.description,
    this.filepath,
     });

  @override
  String toString() {
    return 'DocumentEditRequest[creator=$creator, company=$company, name=$name, description=$description, filepath=$filepath, ]';
  }

  fromJson(Map<String, dynamic>? json) {
    if (json == null) return;
  


        creator = (json[r'creator'] == null) ? null : (json[r'creator'] as int?);

      

        company = (json[r'company'] == null) ? null : (json[r'company'] as int?);

      

        name = (json[r'name'] == null) ? null : (json[r'name'] as String?);

      

        description = (json[r'description'] == null) ? null : (json[r'description'] as String?);

      

        filepath = (json[r'filepath'] == null) ? null : 

      
  }

  DocumentEditRequest.fromJson(Map<String, dynamic>? json) {
    fromJson(json); // allows child classes to call
  }

  Map<String, dynamic> toJson() {
    final json = <String, dynamic>{};
  if (creator != null) {
          json[r'creator'] = creator;
    } 
  if (company != null) {
          json[r'company'] = company;
    } 
  if (name != null) {
          json[r'name'] = name;
    } 
  if (description != null) {
          json[r'description'] = description;
    } 
  if (filepath != null) {
    } 
    return json;
  }
  static List<DocumentEditRequest> listFromJson(List<dynamic>? json) {
    return json == null ? <DocumentEditRequest>[] : json.map((value) => DocumentEditRequest.fromJson(value)).toList();
  }

  static Map<String, DocumentEditRequest> mapFromJson(Map<String, dynamic>? json) {
    final map = <String, DocumentEditRequest>{};
    if (json != null && json.isNotEmpty) {
      json.forEach((String key, dynamic value) => map[key] = DocumentEditRequest.fromJson(value));
    }
    return map;
  }

  @override
  bool operator ==(Object? __other) {
    if (identical(this, __other)) {
      return true;
    }

    if (__other is DocumentEditRequest && runtimeType == __other.runtimeType) {
    return 

     creator == __other.creator &&
  

     company == __other.company &&
  

     name == __other.name &&
  

     description == __other.description &&
  
          filepath == __other.filepath    
    ;
    }

    return false;
  }

  @override
  int get hashCode {
    var hashCode = runtimeType.hashCode;

    
          if (creator != null) {
        hashCode = hashCode * 31 + creator.hashCode;
            }

    
          if (company != null) {
        hashCode = hashCode * 31 + company.hashCode;
            }

    
          if (name != null) {
        hashCode = hashCode * 31 + name.hashCode;
            }

    
          if (description != null) {
        hashCode = hashCode * 31 + description.hashCode;
            }

    
          if (filepath != null) {
        hashCode = hashCode * 31 + filepath.hashCode;
            }

    

    return hashCode;
  }

  DocumentEditRequest copyWith({
         int? creator,
         int? company,
         String? name,
         String? description,
         ApiResponse? filepath,
    }) {

  creator ??= this.creator;
  company ??= this.company;
  name ??= this.name;
  description ??= this.description;
  filepath ??= this.filepath;
  
      final _copy_creator = creator;
        final _copy_company = company;
        final _copy_name = name;
        final _copy_description = description;
        final _copy_filepath = filepath;
  

    return DocumentEditRequest(
      creator: _copy_creator,company: _copy_company,name: _copy_name,description: _copy_description,filepath: _copy_filepath,);
  }
}

what I can immediately see is wrong are the type of the filepath atribute (ApiResponse? instead of MultipartFile?) and the fromJson method in which the syntax for the filepath instantiation is wrong- the third part of the ternary operator along with the semicolon at the end of the line is missing

@NANASHI0X74
Copy link
Contributor Author

I've found this can be worked around with the --type-mappings option: --type-mappings string+binary=MultipartFile

@NANASHI0X74
Copy link
Contributor Author

well, the wrong type can be worked around, but it doesn't fix the faulty fromJson method

@NANASHI0X74
Copy link
Contributor Author

so, with the changes from #55 and #57 I can work around the last problem I'm having by giving the generator my own type mapping: --type-mappings string+binary=Multipartfile.
ideally I'd like to not have to do that... But I see that the generator explicitly sets the type mappings for file and binary type properties to ApiResponse. I'm guessing there's a reason for that? If it didn't break anything I'd just drop those (MultipartFile is the default in AbstractDartCodegen over in the openapi-generator repo), but if not I figure I'll have to set the type in correctInterals again under certain conditions, which right now I'm not sure what those conditions would be.
So, maybe @rvowles could you explain what the ApiResponse type is needed for or rather under which conditions it should be used?

@rvowles
Copy link
Member

rvowles commented Jul 14, 2022

This bit is fixed in 6.1 but the support for MultipartFile is still a bit rubbish. I need to actually nail it down, so I will leave this open until I fix it properly.

@rvowles rvowles added the help wanted Extra attention is needed label Jul 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants