Image can't be uploaded to the server in flutter using DIO - flutter

So I was trying to update my profile user by using a backend framework named ASP.NET core. It works fine when I try to use the API in the postman, it’s 100% working, it changes all of the userprofile from the email, image, and etc. But the thing is when I try to use the API in the flutter, it doesn’t work. When I try to debug it, I found that one of my variables which is in the model can’t catch the multipartfile from an image, and that makes an error.
What I have tried to solve this problem(but still doesn’t work):
I have changed the resolution
I have changed the width and height of the image
POSTMAN Is working
https://i.stack.imgur.com/lj1af.png
UserProfileServices.dart
Future<Response> updateProfile(
File profilePic,
String email,
String password,
String fullName,
String phoneNumber,
DateTime dateOfBirth,
String gender,
String address,
String city,
String province,
String postalcode
)async{
final _path="/user/update-user";
try{
FormData formData= FormData.fromMap(({
"Image": await MultipartFile.fromFile(profilePic.path,
filename: profilePic.path.split("/").last),
"Email":email,
"Password":password,
"FullName":fullName,
"DateOfBirth":dateOfBirth,
"Gender":gender,
"Address":address,
"City":city,
"province":province,
"postalcode":postalcode,
}));
Response response = await httpClient.put(_path,data:formData);
return response;
}
catch(e)
{
print(e);
return e.response;
}
}
Debugging, the profilepic variable was successfully getting the image path, but the image can't catch that
https://i.stack.imgur.com/a5AU7.png

Install and import mime and dio and http(just in case)
import 'package:dio/dio.dart';
import 'package:mime/mime.dart';
import 'package:http_parser/http_parser.dart';
Code
Future<Response> updateProfile(File profilePic,String email,String password,String fullName,String phoneNumber,DateTime dateOfBirth,String gender,String address,String city,String province,String postalcode)async{
final _path="/user/update-user";
try{
Dio dio = new Dio();
final mimeTypeData =lookupMimeType(profilePic.path, headerBytes: [0xFF, 0xD8]).split('/');
FormData formData= FormData.fromMap(({
"Image": await MultipartFile.fromFile(profilePic.path,contentType: MediaType(mimeTypeData[0], mimeTypeData[1]),
"Email":email,
"Password":password,
"FullName":fullName,
"DateOfBirth":dateOfBirth,
"Gender":gender,
"Address":address,
"City":city,
"province":province,
"postalcode":postalcode,
}));
var response = await dio.post("enter your full url for api here",data: formData);
return response;
}
catch(e)
{
print(e);
return e.response;
}
}
Note: Check formData have all values
If you don't want to use Dio you can use Multipart method without dio,you can refer the the following link
flutter-image_upload

My bad guys, there is a missing key at my profile service which is the "phonenumber"key, that makes it an error

Related

i am trying to upload multiple images using dio mathod and multipart but its giving error

when i print _images list it shows that 'instance of multipart' and when i send list of imageFileList this doesn't accept by server.
also what is the use of multipart in sending images?
here is the response error from server response from server error 500
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
var token;
Dio dio = Dio();
List<dynamic>? _images = [];
var apiURL = 'https://denga.r3therapeutic.com/public/api/addpost';
FormData formData = FormData();
Future<String> adminAddproperty({
title,
address,
price,
area,
bedrooms,
bathrooms,
parking,
other,
description,
List<File>? imageFileList,
context,
}) async {
for (int i = 0; i < imageFileList!.length; i++) {
var image = imageFileList[i].path;
_images!.add(
await MultipartFile.fromFile(image, filename: image.split('/').last));
}
FormData formData = FormData.fromMap({
'title': title,
'address': address,
'price': price,
'area': area,
'bedrooms': bedrooms,
'bathrooms': bathrooms,
'parking': parking,
'others': other,
'description': description,
'images[]': imageFileList,
});
SharedPreferences pref = await SharedPreferences.getInstance();
token = pref.getString('token');
print('AdminApisToken =$token');
print('_images');
Response responce;
responce = await dio.post(apiURL,
data: formData,
options: Options(headers: {
HttpHeaders.authorizationHeader: "Bearer $token",
}));
print('Responce: $responce');
return '';
}
I faced a similar situation and I solved it by adding the content type to the MultipartFile, something like this:
await MultipartFile.fromFile(picture.path, contentType: MediaType.parse(image.mimeType)
Or hardcoding the type MediaType('image', 'jpeg'). The MediaType is part of the package:http_parser/http_parser.dart package.
Hope it helps!

How to use the argument from function for body of http request with Dio package

Future<void> login(String email, String password) async {
String url = "https://phone-book-api.herokuapp.com/api/v1/signin";
Response response;
var dio = Dio();
response = await dio.post(url,
data: {"email": email, "password": password);
print(response.data);
}
if i make function with the above code i got some error, but if i fill the body with hard code, it no error happen, and i can receive the response, below the code example
Future<void> login(String email, String password) async {
String url = "https://phone-book-api.herokuapp.com/api/v1/signin";
Response response;
var dio = Dio();
response = await dio.post(url,
data: {"email": "l200140004#gmail.com", "password": "l200140004");
print(response.data);
}
anyone can help me and explaine to me about it case, please...
I am sorry All, my password input is wrong, so it can be error

Flutter http package works on iOS sim, but not on web dev

So I have this piece of my code that handle's some basic post authentication with a django/nginx backend, and when I'm dev testing it on the iOS simulator, it works fine. However, when I am testing it on Flutter web, I keep getting this error.
XMLHttpRequest error.
Any help would be appreciated!
Code in question (the function: working connection, funny enough is working as expected)
static Future<bool> login(String username, String password) async {
final Uri url = Uri.parse(baseUri.toString() + "/api/login/");
var data = jsonEncode({"username": username, "password": password});
if (await workingConneciton()) {
var response = await http.post(url, headers: baseHeader, body: data);
Map<String, dynamic> json = jsonDecode(response.body);
print(response.body);
if (json.containsKey("token")) {
await User.setToken(json["token"]! as String);
return true;
} else {
return false;
}
} else {
return false;
}
}
Most of the times when using an API with flutter ang getting this type of error, adding header("Access-Control-Allow-Origin: *"); to the header might fix the issue

Flutter AZURE BLOB IMAGE UPLOAD - How to upload image captured using mobile camera to azure blob storage

I have been working for few since yesterday to try upload an image to azure blob storage taken using mobile camera form iOS/Android device.
I am able to upload the files but for some reason they being corrupted not able to open the image uploaded.
Please check the image error while opening the uploaded image
I am using flutter package http with different approach all work in uploading image file to azure blob store but it gets corrupted somehow , I tried forcing the ContentType to image/jpeg but no help.
Here is code I am using an http API -
takePicture() async {
final pickedFile = await picker.getImage(source: ImageSource.camera);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
String fileName = basename(pickedFile.path);
uploadFile(fileName, image);
} else {
print('No image selected.');
}
});
}
First approach -->
http.Response response = await http.put(
uri,
headers: {
"Content-Type": 'image/jpeg',
"X-MS-BLOB-TYPE": "BlockBlob",
},
body: image.path,
);
print(response.statusCode);
Using Approach second -->
final data = image.readAsBytesSync();
var dio = Dio();
dio.options.headers['x-ms-blob-type'] = 'BlockBlob';
dio.options.headers['Content-Type'] = 'image/jpeg';
try {
final response = await dio.put(
'$url/$fileName?$token',
data: data,
onSendProgress: (int sent, int total) {
if (total != -1) {
print((sent / total * 100).toStringAsFixed(0) + "%");
}
},
);
print(response.statusCode);
} catch (e) {
print(e);
}
Approach third -->
var request = new http.MultipartRequest("PUT", postUri);
request.headers['X-MS-BLOB-TYPE'] = 'BlockBlob';
request.headers['Content-Type'] = 'image/jpeg';
request.files.add(
new http.MultipartFile.fromBytes(
'picture',
await image.readAsBytes(),
),
);
request.send().then((response) {
uploadResponse.add(response.statusCode);
}, onError: (err) {
print(err);
});
Help here is much appreciated.
If you want to upload the image to Azure Blob Storage in the flutter application, you can use the Dart Package azblob to implement it. Regarding how to use the package, please refer to here.
For example
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'package:azblob/azblob.dart';
import 'package:mime/mime.dart';
...
//use image_picker to get image
Future uploadImageToAzure(BuildContext context) async {
try{
String fileName = basename(_imageFile.path);
// read file as Uint8List
Uint8List content = await _imageFile.readAsBytes();
var storage = AzureStorage.parse('<storage account connection string>');
String container="image";
// get the mine type of the file
String contentType= lookupMimeType(fileName);
await storage.putBlob('/$container/$fileName',bodyBytes: content,contentType: contentType,type: BlobType.BlockBlob);
print("done");
} on AzureStorageException catch(ex){
print(ex.message);
}catch(err){
print(err);
}
Unfortunately, the multipart form is causing break of image. I don't know how it works on azure side, because there is little or no information about multipart uploads, but it's clearly broken because of multipart form. I replicated the problem in .net core application and whenever i am using multipart form data to upload image - it is broken. When i am using simple ByteArrayContent - it works. I couldn't find flutter equivalent to ByteArrayContent, so i am lost now :( The package mentioned by #Jim is useless for me, because i want to give clients sas url, so they have permission to upload image on client side. I do not want to store azure storage account secrets in flutter app.
EDIT. I found the solution to send raw byte data with Dio package. You can do that also with http package.
final dio = new Dio();
final fileBytes = file.readAsBytesSync();
var streamData = Stream.fromIterable(fileBytes.map((e) => [e]));
await dio.put(uploadDestinationUrl,
data: streamData,
options: Options(headers: {
Headers.contentLengthHeader: fileBytes.length,
"x-ms-blob-type": "BlockBlob",
"content-type": "image/jpeg"
}));

Could not upload image with Dio

I'm using Dio to upload images to backend. It often gives me the Reference not set response with a 500 error code. I tried uploading from another source and it seems to be working. What's wrong with this code?
Haven't put the code for performPostRequestWithToken() because other methods are using it too and it seems to be working alright.
Future<UserModel> submitProfileImage(String imagePath) async {
if (isEmpty(imagePath)) throw Exception("NULL image found");
final formdata = FormData.fromMap({
"profilePic": await MultipartFile.fromFile(
imagePath,
filename: "profilePic.png",
),
});
final usertoken = await getCurrentUserToken();
print(usertoken);
final response = await _dioHttpService.performPostRequestWithToken(
"/User/UploadImage",
formdata,
usertoken,
);
if (response.statusCode >= 200 && response.statusCode < 300) {
return UserModel.fromMap(response.data["data"]);
} else {
throw Exception(response.statusMessage);
}
}
The problem in my case was that the map key profilePic was causing the issues. This was definitely a problem from the backend because they were expecting the key to be file.
Changed that and it all worked out.