I am trying to upload multiple image in server using android application which is builds with flutter language. Here is the code which I am trying.
static Future postDataWithFile(......List<File> images) async {
Map<String, String> headers = {
"Accept": "application/json",
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
var request = http.MultipartRequest('POST', Uri.parse(url));
request.headers.addAll(headers);
request.fields['contact'] = insertVisitedPlace.contact;
request.fields['ownerName'] = insertVisitedPlace.ownerName;
request.fields['orgName'] = insertVisitedPlace.orgName;
request.fields['orgtype'] = insertVisitedPlace.orgType.toString();
request.fields['nextFollowup'] = insertVisitedPlace.nextFollowup ?? "";
..............................
Here I am use a List to store all image.
List<MultipartFile> allImagesAfterConvert = [];
images.forEach((image) {
allImagesAfterConvert.add(
await http.MultipartFile.fromPath(
'orgImages',
image.path,
)
);
});
Send request to server to add all images. But In the server get only one image.
request.files.addAll(allImagesAfterConvert);
try {
final response = await request
.send()
.timeout(Duration(seconds: timeoutSeconds), onTimeout: () {
throw TimeoutException("Connection time out. Please try again");
});
return _isValidResponse(response) ? response : _error(response);
} on SocketException {
throw Failure("No Internet Connection");
} on TimeoutException {
throw Failure("Request time out");
} on Error catch (e) {
throw Failure(e.toString());
}
}
Replace orgImages with orgImages[]
images.forEach((image) {
allImagesAfterConvert.add(
await http.MultipartFile.fromPath(
'orgImages[]’,
image.path,
)
);
});
This should work.
Related
Dio interceptor
dio version ^4.0.6
if the API call is error and return status code 401
please edit if there is something can be add
Dio(
BaseOptions(
connectTimeout: 5000,
receiveTimeout: 5000,
responseType: ResponseType.json,
),
)..interceptors.add(InterceptorsWrapper(onRequest: (options, handler) async {
String? token = await StorageService().readAccessToken();
options.headers['Authorization'] = 'Bearer $token';
return handler.next(options);
}, onResponse: (options, handler) {
return handler.next(options);
}, onError: (DioError e, handler) async {
if (e.response != null) {
// check status code for the error
if (e.response!.statusCode == 401) {
RequestOptions requestOptions = e.requestOptions;
call Dio request for refresh the token
await HttpService().postRefreshToken();
String? token = await StorageService().readAccessToken();
final opts = new Options(method: requestOptions.method);
late final response;
if (opts.method == 'GET') {
response = await Dio().get(
requestOptions.path,
options: Options(
method: requestOptions.method,
headers: {'Authorization': 'Bearer $token'},
),
queryParameters: requestOptions.queryParameters,
);
} else {
response = await Dio().post(
requestOptions.path,
options: opts,
data: requestOptions.data,
queryParameters: requestOptions.queryParameters,
);
}
if (response != null) {
handler.resolve(response);
} else {
return null;
}
} else {
handler.next(e);
}
}
}));
this is my code, you can use or copy it as you wish.
also can add something or fix the code if you think the code is not perfect.
i using the ImagePicker package in the dart when i pick the image i want to upload this to the server with the form data but when i try to send this i give this error
" Unhandled Exception: FileSystemException: Cannot retrieve length of file, path = 'File: '/storage/emulated/0/Android/data/com.example.aloteb/files/Pictures/scaled_image_picker3594752094355545880.jpg'' "
and this is my code for sending to the server
var request = http.MultipartRequest('POST', Uri.parse(url));
request.fields.addAll({
'data': '$map'
});
request.files.add(await http.MultipartFile.fromPath('image',picproviderformdate.getPAth.toString()));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
and this is my ImagePickercode
picprovider pic = Provider.of<picprovider>(context,listen: false);
File image = await ImagePicker.pickImage(
source: ImageSource.gallery, imageQuality: 50);
setState(() {
_image = image;
});
print(_image);
pic.setpathe(_image);
can any one help me for solve this problem?
I had a similar problem a while ago, and i used the Dio dependency instead of the classical Http link.
The code is very similar, and i can gave you an example.
final File file = File("${documentDirectory.path}/picture.png");
final httpDio = dio.Dio();
final formData = dio.FormData.fromMap({
"data": "{}",
"files.image": await dio.MultipartFile.fromFile(
"${documentDirectory.path}/picture.png",
filename: "picture.png",
contentType: MediaType('image', 'png'))
});
try {
final dio.Response response = await httpDio.post(
"ApiEndpoint/avatars",
data: formData,
options: dio.Options(headers: {"Authorization": "Bearer yourTokenIfNeeded"}));
if (response.statusCode == 200) {
// Success
}
} on dio.DioError catch (e) {
if (e.response != null) {
// Error
print(e.response.data);
return;
}
}
Don't forgot to update the API endpoint and route as well as your auth authorization if you need one.
I am developing a Flutter Restful web application and the web api backend as asp.net core. When i try to send the form data using post request it is throwing this error
DioError [DioErrorType.RESPONSE]: Http status error [400] Exception
Code
onPressed: () async {
String email_value = emailController.text;
String password_value = passController.text;
String fullname_value = fullnameController.text;
var repassword_value = repassController.text;
print("$email_value");
if (password_value == repassword_value) {
try{
Dio dio = Dio();
var body = jsonEncode(
{
'FullName': '$fullname_value',
'Email': '$email_value',
'Password': '$password_value'
}
);
print("Body" + body);
Response response = await dio.post("http://iamtv.chainuniverse.com/api/Accounts/Register",
data: body,
options: Options(
contentType: Headers.jsonContentType,
)
);
var jsonData = json.decode(response.data);
print(jsonData);
if (response.statusCode > 200 &&
response.statusCode < 250) {
print("Sucess");
await loginAction();
print("Registered");
}
else{
print(jsonData);
}
But when i send data manually without using textcontroller Text it works. Please help me to fix this
Working perfectly in POSTMAN
Late answer, may help you.
I was getting same error with Dio and form-data. It worked! after adding contentType
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
complete code
var dio = Dio();
String fileName = imageFile.path.split('/').last;
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
var response = await dio.post(
"url",
data: formData,
options: Options(
headers: {
"Authorization": auth-token
},
),
onSendProgress: (int sent, int total) {
debugPrint("sent${sent.toString()}" + " total${total.toString()}");
},
).whenComplete(() {
debugPrint("complete:");
}).catchError((onError) {
debugPrint("error:${onError.toString()}");
});
fetch() has been working fine on both iOS and Android until a month ago. I found out that when the response is long it would throw Network request failed error:
Network request failed
onerror
whatwg-fetch.js:504:29
dispatchEvent
event-target.js:172:43
setReadyState
XMLHttpRequest.js:576:29
__didCompleteResponse
XMLHttpRequest.js:392:25
<unknown>
XMLHttpRequest.js:505:8
emit
EventEmitter.js:191:12
__callFunction
MessageQueue.js:344:47
<unknown>
MessageQueue.js:107:26
__guard
MessageQueue.js:291:8
callFunctionReturnFlushedQueue
MessageQueue.js:106:17
This is how I set up fetch requests:
const URLENCODED_HEADER = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
}
async function getToken() {
try {
let response = await fetch(SERVER_URL+'/secure/token', {
credentials: 'include'
});
let responseJson = await response.json();
return responseJson.result
} catch(error) {
throw error;
}
}
async function doLogin(secureInfo) {
formBody = encodeParameters(secureInfo)
try {
let response = await fetch(SERVER_URL+'/user/login', {
method: "POST",
headers: URLENCODED_HEADER,
body: formBody,
credentials: 'include'
});
let responseJson = await response.json();
return responseJson;
} catch(error) {
console.error(error);
throw error;
}
}
Here are some responses that I was able to get back successfully:
1.
err_no: 0
result: BVV7IZVLOYgROXXc
2.
err_no:0
result:{
login_id:xxxx#gmail.com
user_name:""
email: xxx#gmail.com
user_id:11
login_type:1
}
However other longer responses, such as the one below, caused "Network request failed":
{
"err_no":0,
"result":[
{
"article_id":299,
"user_id":11,
"title":"society",
"content":"",
"text_content":"\n",
"tags":"[\"Society\"]",
"used_articles":"{}",
"citation_text":"",
"prompt":"",
"alternative_title":"",
"alternative_prompt":"",
"alternative_cnt":0,
"image_url":"",
"created":"2018-07-26 18:28:17",
"update_time":"2018-07-26 18:28:27"
}
]
}
(logged from web platform)
What could cause this and how should I fix it?
I have a link in the back-end, so I fetch a post request to that link and receive a response. When I alert that response it gives a body init and body text in which I receive datas I need. Everything is good. But..
When I enable remote debugging and console.log that response, it gives body init and body blob (and both are empty). It stucks when I eneble debugging..
Thanks for attention ))
My code:
logIn = async (username, password) => {
// alert(`username : ${username}\n password : ${password}`);
let loginFormData = new FormData();
loginFormData.append('LoginForm[username]', username);
loginFormData.append('LoginForm[password]', password);
loginFormData.append('MacAddress', '111');
loginFormData.append('loginType', 'mobile');
try {
fetch('http://192.168.2.115/araqich_client/general/default/logout', {
method: 'POST',
body: loginFormData
});
let request = fetch('http://192.168.2.115/araqich_client/general/default/login', {
method: 'POST',
body: loginFormData
});
let loginResponseJson = await request;
if (loginResponseJson && loginResponseJson != null ) {
// let loginResponse = JSON.parse(loginResponseJson._bodyInit);
alert(JSON.stringify(loginResponseJson._bodyInit));
let status = loginResponse.status;
if (status) {
let SyncFormData = new FormData();
let accessToken = loginResponse.ACCESS_TOKEN;
SyncFormData.append('ACCESS_TOKEN', accessToken);
SyncFormData.append('MacAddress', '111');
SyncFormData.append('loginType', 'mobile');
let syncRequest = fetch('http://192.168.2.115/araqich_client/mobile/defaultA/syncAndroid', {
method: 'POST',
body: SyncFormData
});
let syncResponseJson = await syncRequest;
if (syncResponseJson && syncResponseJson != null) {
let syncResponse = JSON.parse(syncResponseJson._bodyInit);
let status = syncResponse.status;
if (!status) {
alert('Sorry(( something went wrong...');
} else {
alert('Life is good)))');
}
}
} else {
alert('else1')
}
} else {
alert('else')
}
} catch (error) {
alert(error);
}
}
Instead of using console.log statements, I'd advise using your debugger.