How to upload an image to the server with chopper library? I tried the search on google but, I couldn't manage to get one.
What I have tried is
Function handle creating the chopper client
static ApiService create(String accessToken) {
final client = ChopperClient(
baseUrl: 'http://192.168.43.125:8000/api',
services: [
_$ApiService(),
],
converter: JsonConverter(),
interceptors: [
HeadersInterceptor({
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
}),
HttpLoggingInterceptor()
]);
return _$ApiService(client);}
API
#Post(path: '/inspectionStore',)
#multipart
Future<Response> storeInspection(
#Part("field") String field, #PartFile("file") http.MultipartFile file);
Code that do the work
File actualFile = photoSection.postImage[0];
http.MultipartFile file = await http.MultipartFile.fromPath('file', actualFile.path,contentType: MediaType('image', 'jpg'));
var response = await Provider.of<ApiService>(context).storeInspection('some name',file);
This is what the server retrieve (Laravel Log file)
How can I get a proper data that can be used?
I know it's a little late but this could save someone. So, you need to provide the path to your image as string
#multipart
Future<Response> storeInspection(
#Part("field") String field, #PartFile("file") String file);
then
File actualFile = photoSection.postImage[0];
var response = await Provider.of<ApiService>(context).storeInspection('some name',file.path);
Related
My rest api is working successfully. When I send post request in flutter with Dio. Service always return 500 internal server error.
header
post request
Dio Options
To create a form data use this
var formData = FormData.fromMap({
'user': 'username',
'pass': 'password',
});
response = await dio.post('apiendpoint', data: formData);
I think you are missing the content-type in your header.. based on what your remote accepts either 'application/x-www-form-urlencoded' or 'application/json'
var data = {"phone": mobileNumber, "password": password};
var dio = Dio();
dio.options.headers['content-Type'] = 'application/x-www-form-urlencoded';
try {
var response = await dio.post(ApiUrl.baseUrl + url, data: data);
print(response);
} on DioError catch (e) {
print(e);
}
you can try this way :
var formData = {
'user': 'username',
'pass': 'password',
};
response = await dio.post('apiendpoint', data: jsonEncode(formData));
I'm trying to upload image from React native(without expo) (on Android OS only) to a post endpoint in ASP.net core web API.
In my react native app, I have used 'react-native-image-picker' to capture the image using camera like below.
launchCamera(options, (response: ImagePickerResponse) => {
console.log('Response = ', response);
if (response.assets) {
setVehicle({
...vehicle,
image: {
name: response.assets[0].fileName,
uri: response.assets[0].uri,
type: response.assets[0].type,
},
});
}
});
Once I have the image details is my vehicle state, I'm adding it to form data and doing axios post call like below.
const data = new FormData();
data.append('image', {
name: vehicle.image.name,
uri: vehicle.image.uri,
type: vehicle.image.type,
});
axios.post('https://localhost:44343/api/vehicle', data, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
My post endpoint in ASP.net core web api looks like this.
[Route("")]
[HttpPost]
public IActionResult Post([FromForm(Name = "image")]IFormFile image)
{
//Upload the image to blob storage
}
The image argument variable always contains null value in this endpoint, I tried many think but couldn't fix this. Can anyone help me?😞
Finally found a way to upload images. Not sure if this is the ideal way, but this the only way I could make it work.
After getting the image URI of captured image, I fetched the blob for the image.
const image = await fetch(vehicleImageURI);
const blob = await image.blob();
const fileReaderInstance = new FileReader();
fileReaderInstance.readAsDataURL(blob);
fileReaderInstance.onload = () => {
const base64data = fileReaderInstance.result;
postVehicle({ ...vehicle, base64Image: base64data as string })
.then((res) => {
console.log(res);
})
.catch((ex) => {
console.log(ex);
});
};
On the API side I removed the IFormFile and FromForm from post endpoint and removed the base64image as string.
[Route("")]
[HttpPost]
public IActionResult Post(string image)
{
Regex regex = new Regex(#"^[\w/\:.-]+;base64,");
var base64File = regex.Replace(data.Base64Image, string.Empty);
byte[] imageBytes = Convert.FromBase64String(base64File);
MemoryStream stream = new MemoryStream(imageBytes, 0, imageBytes.Length);
}
Please let us known if you know a better way to do this!🤞
According to node.js Documentation encoding : null when binary data to be sent via Api,
https://www.npmjs.com/package/request in this link below mentioned explanation is found.
encoding - encoding to be used on setEncoding of response data. If
null, the body is returned as a Buffer. Anything else (including the
default value of undefined) will be passed as the encoding parameter
to toString() (meaning this is effectively utf8 by default).
Note: if you expect binary data, you should set encoding: null.
Now I have achieve the same thing in flutter/dart and this encoding parameter is not accepting null as here in node.js they have mentioned.
I want to know how to make this same Post request from Flutter/dart or at least android/java.
var enc = AESCrypt.encrypt(key, iv, JSON.stringify(obj_j));
var output = new Buffer.from(enc, 'hex'); // Buffer
function test() {
console.time("XXX");
request.post({
headers: {
'content-type': 'application/json'
}, //required, or webserver will ignore it application/json multipart/form-data
url: 'http://192.168.29.210/deviceid/read', // webserver url
encoding:null,
body: output
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.timeEnd("XXX");
body = AESCrypt.decrypt(key, iv, body);
//body is decrypted http response, can be parsed with json method
fs.writeFile('input.json', body, function (err) {
if (err) {
return console.error(err);
}
});
}
});
};
Adding code the What i have tried in flutter
var headers = {'Content-Type': 'application/json'};
var request =
http.Request('POST', Uri.parse('http://192.168.29.210/deviceid/read'));
request.body = encryptedText;
request.encoding = null ; // here this null parameter is not acceptable
request.encoding = Encoding.getByName("utf-8")); // only this option is available to add in flutter
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
Even in post man this encoding variable is not present to set it.
Use below flutter framework method
Future<Response> post(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
_withClient((client) =>
client.post(url, headers: headers, body: body, encoding: encoding));
How to use
final url = Uri.parse('$urlPrefix/posts');
final headers = {"Content-type": "application/json"};
final json = '{"title": "Hello", "body": "body text", "userId": 1}';
final response = await post(url, headers: headers, body: json,encoding:null); //here this null parameter is not acceptable
My Final working code is
var headers = {'Content-Type': 'application/json'};
final response = await http.post(
Uri.parse('http://192.168.29.210/deviceid/read'),
headers: headers,
body: encryptedText,
encoding: null);
if (response.statusCode == 200) {
String res = response.body.toString();
//String data = AesEncryption().decryption(res);
print('Body: ${response.body.toString()}');
} else {
print(response.reasonPhrase);
}
print('Status code: ${response.statusCode}');
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()}");
});
this is the code.
Future<http.Response> postRequest () async {
var url ='http://10.0.2.2:3000/api/message';
Map data = {
'message': '12345678901234567890'
};
//encode Map to JSON
var body = json.encode(data);
var response = await http.post(url,
headers: { "accept": "application/json", "content-type": "application/json" },
body: body
);
print("${response.statusCode}");
print("${response.body}");
return response;
}
postRequest();
// also tried this: headers: {"content-type":"application/json" },
In my python flask server, the post message is logging, but with empty body into it.
The flutter app is running on Android Virtual Device and the server is still running on http://0:0:0:0:3000/ and it's using request.get_json() in the method.
Using postman, everything works as expected on my server so I see the problem in the app.
postman details:
POST: http://localhost:3000/api/message
headers
KEY | VALUE
Content-Type | application/json
Body raw
{
"message": "opa"
}
also raised here: https://github.com/flutter/flutter/issues/39351
Try passing :
Future<http.Response> postRequest () async {
var url ='http://10.0.2.2:3000/api/message';
Map<String, String> data = { "message": "opa" };
var body = json.encode(data);
var response = await http.post(url,
headers: { "accept": "application/json", "content-type": "application/json" },
body: body
);
print(response.statusCode);
print(response.body);
return response;
}
postRequest().then((response){
print(response.body);
});
not sure if my finding is precious or not for community, but it seems that the URL was the problem. Everything works now, but I added a / in the end of the string in my flask app.
In Postman, I didn't have to do this. So if you have same problem, take care :)
The log from Flask server:
127.0.0.1 - - [30/Aug/2019 17:41:32] "POST /api/message/ HTTP/1.1" 200 -
opa
My Flask url is:
#app.route('/api/message/', methods=['POST'])
def function():