首页 新闻 会员 周边 捐助

flutter 上传图片报错

0
悬赏园豆:15 [待解决问题]

报_TypeError (type 'Null' is not a subtype of type 'String')这个错误,我打印e.path,e.name都是有值的
var files = imageUploaderController.files
.where((e) => !e.isLast && e.file != null) // 过滤掉 'isLast' 项
.map((e) => e.file)
.toList();
final form = FormData({
'expressno': packageNoController.text,
'position': packagePositionController.text,
'goodcount': packageNumController.text,
'weight': packageWeightController.text,
'account': accountController.text,
'adminid': _storage.read('auth_info_userid'),
});

for (var e in files) {
  if (e == null || e.path == null || e.name == null) {
    Get.log("File does not exist or has invalid path/name.");
    continue;
  }

  form.files.add(MapEntry<String, MultipartFile>(
      'file', MultipartFile(e.path, filename: e.name)));

}

final map = await provider.addPackage(form);
map['msg'].toString().showSnackbar();

if (map['res'] != 1) {
  AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_WARN);
  return;
}
AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_SEND_SUCCESS);
_storage.write('packagePosition', packagePositionController.text);
_storage.save();

onClear();
Ronbinson19920307的主页 Ronbinson19920307 | 初学一级 | 园豆:187
提问于:2024-11-26 15:47
< >
分享
所有回答(2)
0

试一下:

var files = imageUploaderController.files
.where((e) => !e.isLast && e.file != null) // 过滤掉 'isLast' 项
.map((e) => e.file)
.toList();

final form = FormData({
'expressno': packageNoController.text,
'position': packagePositionController.text,
'goodcount': packageNumController.text,
'weight': packageWeightController.text,
'account': accountController.text,
'adminid': _storage.read('auth_info_userid'),
});

for (var e in files) {
if (e == null || e.path == null || e.name == null || e.path!.isEmpty || e.name!.isEmpty) {
Get.log("File does not exist or has invalid path/name.");
continue;
}

form.files.add(MapEntry<String, MultipartFile>(
'file', MultipartFile(e.path!, filename: e.name!))); // 强制解包非空字符串
}

final map = await provider.addPackage(form);
map['msg'].toString().showSnackbar();

if (map['res'] != 1) {
AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_WARN);
return;
}
AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_SEND_SUCCESS);
_storage.write('packagePosition', packagePositionController.text);
_storage.save();

onClear();

sudebao点com | 园豆:432 (菜鸟二级) | 2024-11-27 11:39
0

这个错误 TypeError (type 'Null' is not a subtype of type 'String') 通常意味着代码中某些地方试图将 null 值作为字符串处理。这种问题在 Dart 中比较常见,特别是在使用 null-safety 时。

您提到的代码段涉及到文件上传操作,特别是将文件添加到 FormData 中的处理逻辑。我们来逐步分析问题所在,并给出可能的解决方案。

问题分析

  1. 文件路径和名称的获取
    在您的代码中,e.pathe.name 被直接用于创建 MultipartFile。如果这些值之一为 null,就会抛出您遇到的错误。因此请务必确认这两个值在使用时不是 null

  2. 过滤文件的逻辑
    代码中的过滤条件是:

    var files = imageUploaderController.files
        .where((e) => !e.isLast && e.file != null)
        .map((e) => e.file)
        .toList();
    

    这里您只过滤掉了 e.isLaste.filenull 的情况,但并没有检查 e.file 的内部属性(如路径和名称)是否为 null

解决方案

以下是一些建议来解决该问题:

  1. 增强文件的检查逻辑
    在附件文件之前,确保检查它们的路径和名称。您可以增强 files 的过滤逻辑:

    var files = imageUploaderController.files
        .where((e) => !e.isLast && e.file != null && e.file.path != null && e.file.name != null)
        .map((e) => e.file)
        .toList();
    
  2. 在添加文件之前进行详细检查
    for 循环中,可以加入详细的 null 检查。以下是代码片段的改进版本:

    for (var e in files) {
      if (e == null || e.path == null || e.name == null) {
        Get.log("File does not exist or has invalid path/name.");
        continue;
      }
    
      // 确保这里的 e.path 和 e.name 都不能为 null
      final path = e.path;
      final name = e.name;
    
      if (path == null || name == null) {
        Get.log("File path or name is null for file: $e");
        continue; // 继续下一个文件
      }
    
      form.files.add(MapEntry<String, MultipartFile>(
          'file', MultipartFile(path, filename: name)));
    }
    
  3. Debug Logging
    为了进一步调试问题,可以在创建 MultipartFile 之前,打印出文件路径和文件名,查看实际情况:

    Get.log("Adding file: path=$path, name=$name");
    

最终代码示例

整合上述建议,您的代码可以像这样:

var files = imageUploaderController.files
    .where((e) => !e.isLast && e.file != null && e.file.path != null && e.file.name != null)
    .map((e) => e.file)
    .toList();

final form = FormData({
  'expressno': packageNoController.text,
  'position': packagePositionController.text,
  'goodcount': packageNumController.text,
  'weight': packageWeightController.text,
  'account': accountController.text,
  'adminid': _storage.read('auth_info_userid'),
});

for (var e in files) {
  final path = e.path;
  final name = e.name;

  if (path == null || name == null) {
    Get.log("File path or name is null for file: $e");
    continue;
  }

  form.files.add(MapEntry<String, MultipartFile>('file', MultipartFile(path, filename: name)));
}

final map = await provider.addPackage(form);
map['msg'].toString().showSnackbar();

if (map['res'] != 1) {
  AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_WARN);
  return;
}
AudioPlayerUtil().play(AudioPlayerUtil.SOUNDS_SEND_SUCCESS);
_storage.write('packagePosition', packagePositionController.text);
_storage.save();

onClear();

结论

请根据以上建议更新您的代码。这应该可以解决您所遇到的 TypeError。如果仍然存在问题,请确保逐步调试,检查所有涉及的变量状态。欢迎继续提问以获取进一步的帮助!

Technologyforgood | 园豆:7633 (大侠五级) | 2024-11-27 15:56

我试了下,我是可以获取这些文件,但是我打印日志
Get.log("Request URL: ${request.url}"); 一直是nulll
,if (path == null || name == null) {
Get.log("File path or name is null for file: $e");
continue;
}
你这个我也加了也是没有进去, form.files.add(MapEntry<String, MultipartFile>(
'file', MultipartFile(e.path, filename: e.name)));
只要这个我传了文件就报TypeError (type 'Null' is not a subtype of type 'String')
是在final map = await provider.addPackage(form);这里就报错,可以帮我看下我的这个封装的请求有问题吗
import 'dart:convert';
import 'package:flutter_app/net/base_provider.dart';
import 'package:get_storage/get_storage.dart';
class PackageInputProvider extends BaseProvider {
Future<Map> addPackage(map) async {
final resp = await post('/pda/addpackageAPI.ashx', map);
return jsonDecode(resp.body);
}
}

import 'package:get/get.dart';
import 'package:file_selector/file_selector.dart';
import 'package:flutter_app/lang/translation_service.dart';
import 'package:get/get_connect/http/src/request/request.dart';
import 'package:get_storage/get_storage.dart';

abstract class BaseProvider extends GetConnect {
final _storage = GetStorage();
final _translationService = TranslationService();

BaseProvider() {
onInit();
}

@override
void onInit() {
super.onInit();
baseUrl = 'https://css.com';
httpClient.baseUrl = baseUrl;
timeout = const Duration(minutes: 3);
httpClient.timeout = const Duration(minutes: 3);
httpClient.addRequestModifier<void>((request) async {
var locale = _translationService.getLocale();
request.headers['Accept-Language'] =
'${locale?.languageCode}-${locale?.countryCode}';
request.headers['Authorization'] =
'Bearer ${_storage.read('auth_info_token')}';
Get.log("Request URL: ${request.url}");
Get.log("Files being uploaded: ${request.files}");

  final StringBuffer sb = StringBuffer();
  sb.write(
      "REQUEST URL (${request.method.toUpperCase()}): ${request.url}\n");
  sb.write("PARAMETERS: ${request.files}\n");
  sb.write("BODY: ${await request.bodyBytes.bytesToString()}\n");
  sb.write("HEADERS: ${request.headers}\n");
  sb.write("RESPONSE HEADERS: ${request.headers}\n");
  Get.log(sb.toString());
  return request;
});
httpClient.addResponseModifier<dynamic>((request, response) {
  final StringBuffer sb = StringBuffer();
  sb.write(
      "REQUEST URL (${request.method.toUpperCase()}): ${request.url}\n");
  sb.write("PARAMETERS: ${request.files}\n");
  sb.write("HEADERS: ${request.headers}\n");
  sb.write("RESPONSE HEADERS: ${response.headers}\n");
  sb.write("RESPONSE: ${response.bodyString}");

  Get.log(sb.toString());
  return response;
});

}
}

支持(0) 反对(0) Ronbinson19920307 | 园豆:187 (初学一级) | 2024-11-29 11:00

@Ronbinson19920307: 根据你提供的代码和描述,问题出现在你尝试添加文件到 FormData 并发送请求时。错误信息 TypeError (type 'Null' is not a subtype of type 'String') 表示某个地方期望一个 String 类型的值,但实际上得到了 null。我们可以从几个方面来排查和解决这个问题。

1. 检查 MultipartFile 的构造

确保在创建 MultipartFile 时,e.pathe.name 是有效的字符串。你已经在代码中添加了检查,但可能有其他地方的逻辑导致这些值为 null。建议在创建 MultipartFile 之前,确保打印出这些值:

for (var e in files) {
  // 打印调试信息
  Get.log("File path: ${e.path}, File name: ${e.name}");

  if (e == null || e.path == null || e.name == null) {
    Get.log("File does not exist or has invalid path/name.");
    continue;
  }

  // 这里确保 path 和 name 都是非空字符串
  final filePath = e.path;
  final fileName = e.name;

  // 确保 filePath 和 fileName 是字符串
  if (filePath.isEmpty || fileName.isEmpty) {
    Get.log("File path or name is empty for file: $e");
    continue;
  }

  form.files.add(MapEntry<String, MultipartFile>(
      'file', MultipartFile(filePath, filename: fileName)));
}

2. 检查请求的构造

在你的 BaseProvider 中,确保在发送请求时,map 中的文件确实被添加到了请求中。你可以在 addPackage 方法中添加调试信息,检查 map 的内容:

Future<Map> addPackage(map) async {
  Get.log("Sending package with data: $map");
  final resp = await post('/pda/addpackageAPI.ashx', map);
  return jsonDecode(resp.body);
}

3. 确保 FormData 的构造

确保 FormData 正确构造并包含所有必要的字段。你在创建 FormData 时,确保所有字段都已正确赋值:

final form = FormData({
  'expressno': packageNoController.text,
  'position': packagePositionController.text,
  'goodcount': packageNumController.text,
  'weight': packageWeightController.text,
  'account': accountController.text,
  'adminid': _storage.read('auth_info_userid'), // 确保这个值不是 null
});

// 检查 form 中的内容
Get.log("Form data: ${form.fields}");

4. 请求修改器的调试

在请求修改器中,你添加了调试日志,但要确保 request.files 在这里是有效的。可以在这个地方打印出 request.files 的详细信息:

request.headers['Authorization'] =
    'Bearer ${_storage.read('auth_info_token')}';
Get.log("Request URL: ${request.url}");
Get.log("Files being uploaded: ${request.files}");

// 打印出 request.files 的详细信息
if (request.files != null) {
  for (var file in request.files) {
    Get.log("File: ${file.filename}, Path: ${file.path}");
  }
}

5. 确保请求库的版本

确保你使用的 GetConnectdio 库是最新版本。有时候,库中的 bug 可能会导致意想不到的行为。请检查你的 pubspec.yaml 中的依赖项,确保它们是最新的。

6. 处理响应

在处理响应时,确保你检查返回的数据是否符合预期。如果服务器返回的内容不符合预期,可能会导致 JSON 解码失败。

final map = await provider.addPackage(form);
if (map == null) {
  Get.log("Response map is null");
  return;
}

通过上述步骤,你应该能够更好地调试并找到问题的根源。确保在每一步都添加适当的日志信息,这样可以帮助你确定问题出现的确切位置。如果问题依然存在,请提供更多的上下文信息,例如 e 的类型和结构,或者其他相关的代码片段,以便进行更深入的分析。

支持(0) 反对(0) Technologyforgood | 园豆:7633 (大侠五级) | 2024-12-02 08:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册