Flutter: upload Image error via API function - api

I'm trying to upload images and some data via API from my app and I have no error in my console and I don't know what's wrong with my function.
This is the code which I use:
upload(File imageFile) async {
var user =
Provider.of<LoginUserProvider>(context, listen: false).userData.data;
DateFormat formater = DateFormat('yyyy-MM-dd');
String formatted = formater.format(dateTime);
var stream =
// ignore: deprecated_member_use
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var headers =
Provider.of<LoginUserProvider>(context, listen: false).httpHeader;
var uri = Uri.parse(
"xyz");
var request = new http.MultipartRequest("POST", uri);
request.headers.addAll(headers);
//request.headers.addAll(Environment.requestHeaderMedia);
var multipartFile = new http.MultipartFile(
'attachment',
stream,
length,
filename: imageFile.path,
contentType: MediaType('application', 'x-tar'),
);
request.fields['section_id'] = VillaID.toString();
request.fields['date'] = formatted;
request.fields['description'] = descriptionController.text;
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
try {
final streamedResponse = await request.send();
final response = await http.Response.fromStream(streamedResponse);
print(json.decode(response.body));
final responseData = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode == 200 || response.statusCode == 201) {
return true;
}catch (error) {
print(error);
return false;
}
return true;
}
So can anyone help me with my issue, please!

you are sending the same request twice
1st
var response = await request.send();
Second
final streamedResponse = await request.send();
before sending the same request, create them again.
regarding your code you don't need to create a response again. use the first one in the other places.

Related

HttpClientFactory increased response time with high load

I am connecting to SOAP web service and I am using HttpClientFactory. Application is running on docker. Tester were testing load test with jmeter. After putting more and more load on application response time was increasing forom 100 ms to 50 sec. They have tried Soap service directly and it is performing ok.
var _client = _httpClientFactory.CreateClient("Servis");
var request = new HttpRequestMessage(
HttpMethod.Post,
"")
{
Content = new StringContent(soapRequest, Encoding.UTF8, "text/xml")
};
_client.DefaultRequestHeaders.ConnectionClose = true;
StringContent httpContent = new StringContent(soapRequest, Encoding.UTF8, "text/xml");
using var response = await _client.PostAsync(_client.BaseAddress, httpContent);
var stream = await response.Content.ReadAsStreamAsync();
var content = await _streamHelper.StreamToStringAsync(stream);
if (response.IsSuccessStatusCode)
return content;
throw new ApiException
{
StatusCode = (int)response.StatusCode,
Content = content
};
But I have tried RESTSharp and I have same problem
System.Net.ServicePointManager.DefaultConnectionLimit = 10;
var postUrl = _configuration["OibSettings:BaseAddress"];
IRestClient client = new RestClient();
client.ConfigureWebRequest((r) =>
{
r.ServicePoint.Expect100Continue = false;
r.KeepAlive = false;
});
IRestRequest request = new RestRequest
{
Resource = postUrl,
Method = Method.POST
};
request.AddHeader("Content-Type", "text/xml");
request.AddHeader("Accept", "text/xml");
request.AddParameter("text/xml", soapRequest, ParameterType.RequestBody);
var response = await client.ExecuteAsync(request);
if (response.StatusCode == HttpStatusCode.OK)
return response.Content;
throw new ApiException
{
StatusCode = (int)response.StatusCode,
Content = response.Content
};
It starts working OK but after some time response time start to increse and. Around 5% of responses have extreme time response compared to targeted 100 ms on response.
Also some requests are timeouting and end up in error. But directly jmiter on that service it is ok.

how to get value from api with flutter

I have fake Api
https://fakemyapi.com/api/fake?id=220e0e14-8c78-45e9-9ef0-6ca516fde5be
and I want to print some data, I used this code
var headers = {
'Cookie': '__cfduid=d99061ead63f349023a08a33868eb7ef81619925287'
};
var request = http.Request('GET', Uri.parse('https://fakemyapi.com/api/fake?id=220e0e14-8c78-45e9-9ef0-6ca516fde5be'));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
and I get this response.
I/flutter (17790): {"first_ame":"Miguel","last_name":"Fay","photo":"https://s3.amazonaws.com/uifaces/faces/twitter/dhooyenga/128.jpg","email":"Keven.Cole#gmail.com","title":"Regional Functionality Developer","job_type":"Supervisor","telephone":["567.700.9452","1-701-720-0774 x9918","1-716-687-6317 x670"],"address":{"zip_code":"20909","street":"Myrtis Pines","city":"West Mekhifort","country":"Greece"},"friends":[{"first_name":"Carlie","last_name":"Kilback","email":"Erich_Emmerich90#gmail.com"},{"first_name":"Clarabelle","last_name":"Runolfsson","email":"Elise_Schroeder#gmail.com"}]}
so how to print the first name and zip code?
finally I got this solve by trying again and again,
var headers = {
'Cookie': '__cfduid=d99061ead63f349023a08a33868eb7ef81619925287'
};
var request = http.Request(
'GET',
Uri.parse(
'https://fakemyapi.com/api/fake?id=220e0e14-8c78-45e9-9ef0-6ca516fde5be'));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
var item =
JsonDecoder().convert("${await response.stream.bytesToString()}");
print("item $item");
print("first_ame ${item['first_ame']}");
return item;
} else {
print(response.reasonPhrase);
}

oauth2 in core 3.1

I am using core 3.1 to connect to the canvas API, this is part of my code..
services.AddAuthentication(config =>
{
config.DefaultAuthenticateScheme = "CanvasCookies";
config.DefaultSignInScheme = "CanvasCookies";
config.DefaultChallengeScheme = "CanvasLMS";
})
.AddCookie("CanvasCookies")
.AddOAuth("CanvasLMS", config =>
{
var canvas_domain = Configuration.GetValue<string>("Canvas:Domain");
var client_secret = Configuration.GetValue<string>("Canvas:Secret");
var client_id = Configuration.GetValue<string>("Canvas:Client_id");
config.ClientId = client_id;
config.ClientSecret = client_secret;
config.CallbackPath = new PathString("/oauth/callback");
//config.Scope.Add("google.com")
config.AuthorizationEndpoint = $"{canvas_domain}login/oauth2/auth";
config.TokenEndpoint = $"{canvas_domain}login/oauth2/token";
config.UserInformationEndpoint = $"{canvas_domain}api/v1/users//courses";
config.SaveTokens = true;
config.Events = new OAuthEvents()
{
OnCreatingTicket = context =>
{
var accessToken = context.AccessToken;
var base64payload = accessToken.Split('.')[1];
var bytes = Convert.FromBase64String(base64payload);
var jsonPayload = Encoding.UTF8.GetString(bytes);
var claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonPayload);
foreach(var claim in claims)
{
context.Identity.AddClaim(new Claim(claim.Key, claim.Value));
}
return Task.CompletedTask;
}
this is the controller
public class APICanvasController : Controller
{
...
[Authorize]
public async Task<IActionResult> Secret()
{
var serverResponse = await AccessTokenRefreshWrapper(
() => SecuredGetRequest("https://localhost:44388/secret/index"));
var apiResponse = await AccessTokenRefreshWrapper(
() => SecuredGetRequest("https://localhost:44388/secret/index"));
return View();
}
private async Task<HttpResponseMessage> SecuredGetRequest(string url)
{
var token = await HttpContext.GetTokenAsync("access_token");
var client = _httpClientFactory.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
return await client.GetAsync(url);
}
public async Task<HttpResponseMessage> AccessTokenRefreshWrapper(
Func<Task<HttpResponseMessage>> initialRequest)
{
var response = await initialRequest();
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
await RefreshAccessToken();
response = await initialRequest();
}
return response;
}
private async Task RefreshAccessToken()
{
...
}
}
}
when I execute the code I obtain this error
Exception: The oauth state was missing or invalid.
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
Any idea what I am doing wrong?
Thanks
CallbackPath is not supposed to refer to a controller, it refers to a unique path handled by the auth middleware. It will redirect back to your controller when it's done.
"/oauth/callback" should handle oauth authentication result as a json instead of page.

Flutter : Multipart File request not working

I want to upload image by multipart File request. With using this code When I pass two image files then it's working fine. But when I want to pass one image file and another is null then it's not working.
where is the problem? How can I solve this ?
Here is my code -
Future<Map<String, dynamic>> updateprofile(
UpdateProfileInfo updateProfileInfo,
File imageFile,
File signatureFile) async {
String url = "$baseAPIUrl/update-profile-info";
String _token = await SavedData().loadToken();
String authorization = "Bearer $_token";
final headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
"Authorization": authorization
};
var request = http.MultipartRequest("POST", Uri.parse(url));
request.headers.addAll(headers);
request.fields.addAll(updateProfileInfo.toJson());
request.files
.add(await http.MultipartFile.fromPath('image', imageFile.path));
request.files.add(
await http.MultipartFile.fromPath('signature', signatureFile.path));
print(" Update Profile Json ${updateProfileInfo.toJson()}");
print("Request Fields ${request.fields}");
http.StreamedResponse response = await request.send();
String respStr = await response.stream.bytesToString();
dynamic respJson;
try {
respJson = jsonDecode(respStr);
} on FormatException catch (e) {
print(e.toString());
}
print('API ${response.statusCode}\n $respJson');
bool isSuccess = response.statusCode == 200;
var data = json.decode(respStr);
return {
'isSuccess': isSuccess,
"message": isSuccess ? data["success"]["message"] : null,
"name": isSuccess ? data["success"]["name"] : null,
"classgroup": isSuccess ? data["success"]["classgroup"] : null,
"image": isSuccess ? data["success"]["image"] : null,
"error": isSuccess ? null : data['error']['message'],
};
}
Here is postman Screenshot
1.
2. POSTMAN Generated code for Dart - http
when one of your file is null, you should avoid adding it to the request body.
if(imageFile != null){
request.files
.add(await http.MultipartFile.fromPath('image', imageFile.path));
}
if(signatureFile != null){
request.files.add(
await http.MultipartFile.fromPath('signature', signatureFile.path));
}
its because signatureFile.path is going to cause an error here
using dio package should work
Future<bool> updateImage(var pickedFile) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();` <br/>
var token = sharedPreferences.getString("token");
Dio dio = Dio();
final File file = File(pickedFile.path);
String fileName = file.path.split('/').last;
dio.options.headers["authorization"] = token;
FormData formData = FormData.fromMap({
"image": await MultipartFile.fromFile(file.path),
});
try {
var response = await dio.post(API.kBASE_URL, data: formData);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
} catch (r) {
return false;
}
}

flutter send empty file to server

Hi i'm trying to upload a file to a server via a flutter app but the file is always empty.
it was working fine and after that it stopped working.
here is my code :
static uploadImageToServer(String image) async {
File imageFile = new File(image);
Map<String, String> headers = {
'Content-Type': 'multipart/form-data',
'Accept-Charset': 'UTF-8'
};
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
print(imageFile.path);
var uri = Uri.parse("http://planning.test/test_image");
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('File', stream, length,
filename: "test_image_failure.jpg");
request.headers.addAll(headers);
request.fields['Destination'] = '/';
print("**********");
print(multipartFile.filename);
print(uri);
print(multipartFile.length);
print("**********");
request.files.add(multipartFile);
print(request.contentLength);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
and with dio package
_dioUpload(String imageFile)async {
var dio = Dio();
var formData = FormData();
formData.files.add(MapEntry(
"File",
await MultipartFile.fromFile(imageFile, filename: "xx.png"),
));
print(formData.files.first.value.length);
var response = await dio.post(
"http://planning.test/test_image",
data: formData,
onSendProgress: (received, total) {
if (total != -1) {
print((received / total * 100).toStringAsFixed(0) + "%");
}
},
);
print(response);
}
i don't understand what is happening everything look fine and the file exist.
thx
I'm using the retrofit for flutter and to send an empty file I got it as follows.
File.fromRawPath(Uint8List.fromList([0]))
Retrofit example
#PUT('profile')
#FormUrlEncoded()
Future<void> update(#Header("Authorization") String token,
#Field() String name, #Field() String surname, #Part() File avatar);
Example
await myapi.update("_token_","Sr", "Burton", File.fromRawPath(Uint8List.fromList([0])));