使用swagger_dart_code_generator生成Multipart请求代码异常求助
swagger_dart_code_generator生成multipart/form-data请求异常的解决方法
我在Flutter项目中使用swagger_dart_code_generator基于openapi.json生成接口代码时,遇到了multipart/form-data类型请求的处理问题:application/json类型请求正常,但上传文件的multipart请求生成的代码不符合预期,导致接口调用失败。已通过Swagger Web UI验证目标API可用,相关信息如下:
相关OpenAPI定义片段
"post": { "operationId": "ImageListApiView_post_images_post", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/ImageMetaForm" } } }, "required": true }, /* ... */ },
"ImageMetaForm": { "properties": { "file": { "description": "The image to upload.", "format": "binary", "title": "File", "type": "string" } }, "required": [ "file" ], "title": "ImageMetaForm", "type": "object" },
生成的Dart代码
@override Future<Response<ResponseImageMetaTDO>> _apiV1ImagesPost( {required ImageMetaForm body}) { final Uri $url = Uri.parse('/api/v1/images'); final List<PartValue> $parts = <PartValue>[ PartValue<ImageMetaForm>( 'body', body, ) ]; final Request $request = Request( 'POST', $url, client.baseUrl, parts: $parts, multipart: true, ); return client.send<ResponseImageMetaTDO, ResponseImageMetaTDO>($request); }
实际发送的请求体
--dart-http-boundary-AJQBeUhjoUmCi.dny6r+q.hDb4gsBJeLma6Abmbpwx+0uiiNv4l content-disposition: form-data; name="body" {"file":"/home/melidon/Pictures/IMG_20230816_192752.jpg" } --dart-http-boundary-AJQBeUhjoUmCi.dny6r+q.hDb4gsBJeLma6Abmbpwx+0uiiNv4l--
问题分析
生成器错误地将整个ImageMetaForm对象序列化为JSON字符串,并作为body字段放入multipart请求中,而正确的multipart/form-data请求应该将file字段作为独立的文件part发送,直接传递文件内容而非文件路径的JSON。
解决方案
1. 升级swagger_dart_code_generator版本
该问题大概率是生成器旧版本的解析bug,先将依赖升级到最新稳定版,重新生成代码:
在pubspec.yaml中更新版本:
dependencies: swagger_dart_code_generator: ^最新版本号
执行flutter pub get后重新生成接口代码,验证是否修复。
2. 手动修正生成的代码
如果暂时无法升级生成器,可手动修改生成的接口方法,将文件字段作为PartValueFile传递:
import 'dart:io'; import 'package:path/path.dart' as path; @override Future<Response<ResponseImageMetaTDO>> _apiV1ImagesPost( {required ImageMetaForm body}) { final Uri $url = Uri.parse('/api/v1/images'); final List<PartValue> $parts = <PartValue>[ PartValueFile( 'file', File(body.file), // 若body.file是Uint8List则直接传入 filename: path.basename(body.file), // 可选:指定文件名 ) ]; final Request $request = Request( 'POST', $url, client.baseUrl, parts: $parts, multipart: true, ); return client.send<ResponseImageMetaTDO, ResponseImageMetaTDO>($request); }
3. 调整OpenAPI定义格式
部分情况下,生成器对引用类型的multipart schema解析存在问题,可尝试将schema直接内联在requestBody中,而非引用组件:
"post": { "operationId": "ImageListApiView_post_images_post", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "description": "The image to upload.", "format": "binary", "title": "File", "type": "string" } }, "required": ["file"] } } }, "required": true }, /* ... */ },
调整后重新生成代码,看是否能正确生成文件上传的multipart请求结构。
内容的提问来源于stack exchange,提问作者Zsombor Szommer
相关产品推荐
相关产品推荐

