#flutter #post #multipartform-data #filepicker.io
Вопрос:
Я пытаюсь отправить некоторые данные и файл на сервер js моего узла. Файл представляет собой файл .txt, и я использую FilePicker для получения файла и многочастного запроса для его отправки.
Это виджет с текстовыми формами и кнопкой вложения:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Crear una nueva tarea'),
backgroundColor: Colors.green[300],
),
body: ChangeNotifierProvider<LoginFormProvider>(
create: (context) => LoginFormProvider(),
child: Consumer<LoginFormProvider>(builder: (context, value, child) {
final loginFormProvider =
Provider.of<LoginFormProvider>(context, listen: true);
return Container(
color: Colors.grey[100],
padding: EdgeInsets.symmetric(horizontal: 20),
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: 370),
child: Form(
key: loginFormProvider.formKey,
child: Column(
children: [
TextFormField(
onChanged: (value) =>
loginFormProvider.title = value,
decoration: buildInputDecoration(
hint: 'Enunciado',
label: 'Enunciado de la tarea',
icon: Icons.title),
),
SizedBox(
height: 20,
),
TextFormField(
onChanged: (value) =>
loginFormProvider.date = value,
cursorColor: Colors.green,
decoration: buildInputDecoration(
hint: 'Fecha limite',
label: 'Fecha limite de entrega',
icon: Icons.date_range),
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () async {
final result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['txt', 'docx'],
);
final file = result!.files.first.name;
value.setFile(result);
},
child: Text('Seleccionar archivo')),
SizedBox(
height: 20,
),
CustomOutlinedButton(
onPressed: () async {
if (value.file == null) return;
value.makePostRequest(loginFormProvider.title,
id, teacherID, loginFormProvider.date);
Navigator.pop(context);
},
text: 'Crear Tarea'),
],
),
),
),
));
})),
);
}
И я пытаюсь отправить запрос следующим образом в этом классе:
class LoginFormProvider extends ChangeNotifier {
GlobalKey<FormState> formKey = new GlobalKey<FormState>();
var file;
String role = '';
String id = '';
String lastname = '';
String firstname = '';
String password = '';
String tid = '';
String name = '';
String title = '';
int teacherid = 0;
int subjectid = 0;
String date = '';
bool validateForm() {
if (formKey.currentState!.validate()) {
return true;
} else {
return false;
}
}
Future setFile(txt) async {
this.file = txt;
this.notifyListeners();
}
Future makePostRequest(
String title, int subjectid, int teacherid, String limitDate) async {
var url = Uri.parse('http://localhost:8000/newHomework');
var request = http.MultipartRequest('POST', url);
var headers = {'Content-Type': 'text/plain; charset=UTF-8'};
File fileByte = this.file;
Uint8List data = await fileByte.readAsBytes();
List<int> list = data.cast();
request.files
.add(http.MultipartFile.fromBytes('text', list, filename: 'tarea1'));
request.headers.addAll(headers);
request.fields['title'] = title;
request.fields['limitDate'] = limitDate;
request.fields['subjectid'] = subjectid.toString();
request.fields['teacherid'] = teacherid.toString();
request.fields['ext'] = '.txt';
var res = await request.send();
return res.stream.bytesToString().asStream().listen((event) {
var parsedJson = json.decode(event);
print(parsedJson);
});
}
}
И я получаю Expected a value of type 'File', but got one of type 'FilePickerResult'
Я не знаю, как это исправить, чтобы отправить файл… Есть какие-нибудь идеи о том, как пройти через это?
Комментарии:
1. требуется тип файла, но вы возвращаете результат FilePickerPickerResult. Также поделитесь полным кодом, потому что я не вижу makePostRequest в вызываемой функции.
2. Вы правы, мои извинения. Я обновил вопрос с помощью кнопки, которая отправляет данные, это пользовательская кнопка под названием
CustomOutlinedButton
.3. Вы решили эту проблему? потому что вы возвращаете FilePickerResult, и ему нужен файл.
4. Нет, я получаю указанную ошибку, код, который вы видите, — это код, который я запускаю, но когда я нажимаю кнопку
Expected a value of type 'File', but got one of type 'FilePickerResult'
Customoutlined, появляется ошибка5. @Ирвин, откуда ты берешь « Файловый файл = этот.файл«
Ответ №1:
Что вы делаете неправильно, так это устанавливаете FilePickerResult вместо файла. [Отредактировано с использованием другого подхода для Интернета.
ElevatedButton(
onPressed: () async {
final result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['txt', 'docx'],
withReadStream:
true,
);
//Edited Part
var file = result!.files.single;
value.setFile(file);
},
child: Text('Seleccionar archivo'))
а также
PlatformFile file = null;
Future setFile(PlatformFile txt) async {
this.file = txt;
this.notifyListeners();
}
Future makePostRequest(
String title, int subjectid, int teacherid, String limitDate) async {
var url = Uri.parse('http://localhost:8000/newHomework');
var request = http.MultipartRequest('POST', url);
var headers = {'Content-Type': 'text/plain; charset=UTF-8'};
request.files.add(new http.MultipartFile(
"text", file.readStream, file.size,
filename: "tarea1"));
request.headers.addAll(headers);
request.fields['title'] = title;
request.fields['limitDate'] = limitDate;
request.fields['subjectid'] = subjectid.toString();
request.fields['teacherid'] = teacherid.toString();
request.fields['ext'] = '.txt';
var res = await request.send();
return res.stream.bytesToString().asStream().listen((event) {
var parsedJson = json.decode(event);
print(parsedJson);
});
}
Комментарии:
1. Эта строка
File file = File(result!.files.single.path);
выдает ошибку:2 positional argument(s) expected, but 1 found. Try adding the missing
и также говорит:The argument type 'String?' can't be assigned to the parameter type 'List<Object>'.
2. Сделал это:
File file = File(result!.files, result.files.single.name); value.setFile(file);
и получил эту ошибку:Error: Expected a value of type 'File', but got one of type 'File$'
3. @Irwin В какой строке вы получаете ошибку.
value.setFile(result);
4. Я получил сообщение об ошибке здесь:
File file = File(result!.files.single.path);
поэтому я обновил его доFile file = File(result!.files, result.files.single.name);
» Важно ли упомянуть, что это веб-сайт Flutter?»5. @Irwin Нет, это не так. потому что плагин поддерживает все платформы. Включая веб. только что обновил ответ. попробуй это.