type 'String' is not a subtype of type 'Map<String, dynamic>' in type cast
我正在开发一个 Flutter 应用程序,用户可以在其中更新他们的个人资料,包括上传个人资料图片和封面照片。我正在使用 Dio 处理 HTTP 请求和分段文件上传。
我无法将图像文件(例如,个人资料图片和封面照片)上传到后端。请求不断失败,并出现与 FormData 格式化方式相关的错误。我怀疑 Dio 没有正确解释 FormData。
下面是我的代码的简化版本。
Future<void> updateUserProfile({
File? coverPhoto,
File? profilePhoto,
}) async {
try {
// Prepare the form data with fields
FormData formData = FormData.fromMap({
"first_name": "Tupac",
"last_name": "shakur",
"email": "[email protected]",
});
// Add cover photo if it exists
if (coverPhoto != null) {
final result = _preparePhotoFile(coverPhoto, "cover photo");
if (result is String) {
print(result);
return; // Stop if there's an error
}
final [type, subtype] = result as List<String>;
formData.files.add(
MapEntry(
"cover_photo",
await MultipartFile.fromFile(
coverPhoto.path,
filename: path.basename(coverPhoto.path),
contentType: MediaType(type, subtype),
),
),
);
}
// Add profile photo if it exists
if (profilePhoto != null) {
final result = _preparePhotoFile(profilePhoto, "profile picture");
if (result is String) {
print(result);
return; // Stop if there's an error
}
final [type, subtype] = result as List<String>;
formData.files.add(
MapEntry(
"profile_picture",
await MultipartFile.fromFile(
profilePhoto.path,
filename: path.basename(profilePhoto.path),
contentType: MediaType(type, subtype),
),
),
);
}
// Sending the request
Dio dio = Dio();
final response = await dio.post(
"https://example.com/update-profile",
data: formData,
options: Options(contentType: "multipart/form-data"),
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}
/// Prepares the photo file by validating its MIME type and ensuring it's in an accepted format.
dynamic _preparePhotoFile(File photo, String fieldName) {
// Determine MIME type of the file
final mimeType = lookupMimeType(photo.path);
// Validate MIME type is supported
if (mimeType == null) {
return 'Unsupported image format for $fieldName';
}
// Check if MIME type is among the supported image formats
if (!['image/jpeg', 'image/png', 'image/bmp', 'image/webp'].contains(mimeType)) {
return 'Unsupported image format for $fieldName';
}
// Return MIME type split into type and subtype (e.g., "image/jpeg" -> "image", "jpeg")
return mimeType.split('/');
}
我已采取的故障排除步骤:
似乎
FormData.fromMap()
可能无法正确编码文件数据。您可以尝试将其替换为包含 JSON 数据和文件对象的简单 Map<String, dynamic>
,然后使用 FormData
对其进行编码。这是示例代码:
Future<void> updateUserProfile({
File? coverPhoto,
File? profilePhoto,
}) async {
try {
Map<String, dynamic> formDataMap = {
"first_name": "Tupac",
"last_name": "shakur",
"email": "[email protected]",
};
// Prepare the form data with fields
// FormData formData = FormData.fromMap({
// "first_name": "Tupac",
// "last_name": "shakur",
// "email": "[email protected]",
// });
// Add cover photo if it exists
if (coverPhoto != null) {
final result = _preparePhotoFile(coverPhoto, "cover photo");
if (result is String) {
print(result);
return; // Stop if there's an error
}
final [type, subtype] = result as List<String>;
formDataMap.addAll({"cover_photo": await MultipartFile.fromFile(
coverPhoto.path,
filename: path.basename(coverPhoto.path),
contentType: MediaType(type, subtype),
)});
// formData.files.add(
// MapEntry(
// "cover_photo",
// await MultipartFile.fromFile(
// coverPhoto.path,
// filename: path.basename(coverPhoto.path),
// contentType: MediaType(type, subtype),
// ),
// ),
// );
}
// Add profile photo if it exists
if (profilePhoto != null) {
final result = _preparePhotoFile(profilePhoto, "profile picture");
if (result is String) {
print(result);
return; // Stop if there's an error
}
final [type, subtype] = result as List<String>;
formDataMap.addAll({"profile_picture": await MultipartFile.fromFile(
profilePhoto.path,
filename: path.basename(profilePhoto.path),
contentType: MediaType(type, subtype),
)});
// formData.files.add(
// MapEntry(
// "profile_picture",
// await MultipartFile.fromFile(
// profilePhoto.path,
// filename: path.basename(profilePhoto.path),
// contentType: MediaType(type, subtype),
// ),
// ),
// );
}
// Sending the request
Dio dio = Dio();
final response = await dio.post(
"https://example.com/update-profile",
data: FormData.fromMap(formDataMap),
options: Options(contentType: "multipart/form-data"),
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}