Xamarin forms: Method is left after callunt await client.GetAsync - xamarin.forms

I am getting data from a server via Rest API. But Whenever i am waiting for the client response the Methos is left by the Debugger and the Program start loading the GUI even though at this point there is no Data to Display. Im already stuck for a couple of days on it. How can i make the Code to wait for the Response? Iam already using Await
My Method to get The Data: (Client Call in Line 8)
public async Task<ObservableCollection<Datensatz>> getDataFromAzure()
{
string URL = URLForContent;
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("ApiKey", PW);
var result1 = await _client.GetAsync(URL, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (result1.StatusCode == System.Net.HttpStatusCode.OK)
{
var result = await result1.Content.ReadAsStringAsync();
var ContentFromJson = JsonConvert.DeserializeObject<ObservableCollection<Datensatz>>(result);
string json = JsonConvert.SerializeObject(ContentFromJson, Formatting.Indented);
var filename = #"data.json";
var destinatioPath = Path.Combine(Android.App.Application.Context.GetExternalFilesDir(null).ToString(), filename);
File.WriteAllText(destinatioPath, json);
App.Database_Main.FillMainDBWithJsonEntrys();
return ContentFromJson;
}
return null;
}

You can use the Wait method of the Task. Such as
Task result = getDataFromAzure()
result.Wait();
You can also use the Thread.sleep(1000) to make the main thread sleep for a while. But this will reduce the function of the application because we don't know how long time the async method need and if the time if more than 5 seconds will cause the ANR.

Related

Flutter : InternalError , Filter error, bad data when upload image on server

I do simple upload image to server using http packages. But the problem is , when i upload it i got error Unhandled Exception: InternalError: 'Filter error, bad data'.
Upload
Future testUpload(File selfieImage, String pembertang) async {
final result = await reusableRequestServer.requestServer(() async {
//create multipart request for POST or PATCH method
var request = http.MultipartRequest('POST', Uri.parse('$baseApiUtang/addUtang'));
//add text fields
request.fields['pembertang'] = '$pembertang';
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath('selfie', selfieImage.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print('responseData : $responseData');
print('responseString : $responseString');
return responseString;
});
return result;
}
With this strange problem , i try it with postman but it's work like i want.
My opinion, it's not problem in my backend code. I missed something ?
Update
Similiar problem with me on this issue
Update 2
When i look inside the code and print variable 1 by 1, i got status code 403
Hi can you pls try following code
var stream = new http.ByteStream(Stream.castFrom(imageFile.openRead()));
// get file length
var length = await imageFile.length();
// create multipart request
var request = new http.MultipartRequest("POST", uri);
var name = firstname +"."+imageFile.path.split(".").last;
// multipart that takes file
var multipartFile = new http.MultipartFile('profile', stream, length,
filename: basename(name));
In my case my can not take so much long name so i customise image name and then tried and its working .
so you can also try this.

AWS Lambda function returns no records if call from Xamarin Forms

I am having troubles trying to get information back from a Lambda Function in AWS. The Lambda function is behind API Gateway.
If I run the function straight from the Lambda console or from the API, works ok. If I call it with this code returns [].
I am not getting any problems if the token is correct and I can see inside the Lambda function the parameter 'LastUpdate'.
Here is the code:
public async Task<string> GetUpdates(long ticksLastCheck, string token)
{
string Error = "";
string response = "";
object data = new
{
LastUpdate = ticksLastCheck
};
var myContent = JsonConvert.SerializeObject(data);
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
//I have tested without ConfigureAwait and did not work either
var responseSync = await _client.PostAsync("getUpdates", byteContent).ConfigureAwait(false);
if (responseSync != null)
{
//I have tested with await and did not work either. With await ".Result" should be removed from the line below.
var response2 = responseSync.Content.ReadAsStringAsync();
response = response2.Result;
}
return response;
}
If I call it from Postman works as well. Is there any header or parameter that Postman sends and I am missing?
My bad. The field in DynamoDB is a string and I was sending it as a long and never converting to string.
So as soon as I change:
object data = new
{
LastUpdate = ticksLastCheck
};
into this
object data = new
{
LastUpdate = ticksLastCheck.ToString()
};
I am getting the expected response.
Thank you.

Issue with Xamarin App and Web API Model Binding: Object passed to service is null only on iOS

I have been running into a very strange issue, and I am not even sure if this is an issue with my app or the web service I am calling.
I have a Web API Service with a Post method that accepts a complex parameter (it is my own custom object). In my Xamarin project I have some pretty straightforward code to call this service:
public async Task SubmitEReport(decimal amount, DateTime receivedDate,
byte[] image)
{
try
{
HttpClient client = new HttpClient();
var uri = new Uri("https://services.example.com/EPub/api/Expense/");
var eReport = new eReport()
{
UserName = "EMPLOYEE\" + Application.Current.Properties["username"].ToString(),
Cost = amount,
ReceivedDate= receivedDate,
ReceiptImageExtension = "jpg",
SubmittalDate = DateTime.Now,
Image = image
};
var json = JsonConvert.SerializeObject(eReport );
var content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
content.Headers.Add("authorize-token", Application.Current.Properties["auth-token"] as string);
HttpResponseMessage response = null;
response = await client.PostAsync(uri, content);
var eResult = new EResult()
{
Success = response.IsSuccessStatusCode,
ErrorMessage = response.ReasonPhrase
};
return eResult ;
}
catch (Exception ex)
{
var errorResult = new eResult () { Success = false, ErrorMessage = ex.Message };
return errorResult;
}
}
The issue that I am having is that, when I test this on an Android the code works as expected: the service is called, the object passed over is not null and has the data in it. In short, the parameter binding works as expected. The same is not so on iOS: when I call the service using the app on an iPhone, I can see that it is reaching the service and the Post method, but the parameter binding is not working correctly as the object I am passing over is always null.
The issue is resolved. The problem was actually the size of the request. I discovered this in my Web Api service after examining the contents of the request object, and received an exception that the request length was exceeded. My solution was to increase the value of the property maxrequestlength in the web.config. This still does not explain why the request is so much larger in iOS than Android. Will follow up on this.
try to debug your code without using any async methods. async methods should work in general without any problems, but it's sometimes hard to comprehend how implemented logic actually behaves.

ASP.NET call hangs on async await

My calls to a Google API from an API Controller in IIS express hang indefinitely when called sequentially using async await.
var id = CreateDocument("My Title").Result;
async Task<string> CreateDocument(string title)
{
var file = new GData.File { Title = title };
// Stepping over this line in the debugger never returns in IIS Express.
file = await Service.Files.Insert(file).ExecuteAsync();
return file.Id;
}
It does not hang calling the same method from a test console app.
The same logic also does not hang IIS Express when called using the corresponding synchronous method instead.
var id = CreateDocument("My Title");
string CreateDocument(string title)
{
var file = new GData.File { Title = title };
// This has no problem
file = Service.Files.Insert(file).Execute();
return file.Id;
}
Where should I look for the defect?
The defect is here:
var id = CreateDocument("My Title").Result;
As I explain on my blog, you should not block on async code.
Instead of Result, use await:
var id = await CreateDocument("My Title");

Windows Phone 8 Hanging on GetFolderAsync and OpenStreamForReadAsync

I am making a windows phone 8 application. Part of this application requires state to be saved. I am saving it as a string of Json. If I open the application, save some data, exit the application and the load it again, it hangs on either GetFolderAsync or OpenStreamForReadAsync. It does not happen every time, but once it starts hanging, I have to kill the whole emulator and make a new one to start the application again.
I have even tried just making an empty file with no data in it and the problem still persistes.
Below is the code I am using to save and load the data. It does not matter where I call the data load whether it be on application start or on the form load it still breaks.
private async Task SaveLists()
{
//XmlSerializer serializer = new XmlSerializer(typeof(ListHolder));
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("Lists.json",
CreationCollisionOption.ReplaceExisting);
string json = JsonConvert.SerializeObject(Lists, Formatting.Indented);
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(json.ToCharArray());
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
private async Task LoadLists()
{
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
try
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("DataFolder");
// Get the file.
var files = dataFolder.GetFilesAsync();
var file = await dataFolder.OpenStreamForReadAsync("Lists.json");
string jsonString = "";
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
jsonString = streamReader.ReadToEnd();
}
if (jsonString.Length > 0)
{
Lists = JsonConvert.DeserializeObject<List<ItemList>>(jsonString);
}
else
{
Lists = new List<ItemList>();
}
}
catch (Exception ex)
{
Lists = new List<ItemList>();
}
}
}
You are causing a deadlock by calling Result. I explain this deadlock on my blog and in a recent MSDN article. In summary, await will (by default) attempt to resume execution within a context (the current SynchronizationContext unless it is null, in which case it uses the current TaskScheduler).
In your case, the current SynchronizationContext is the UI context, which is only used by the UI thread. So when you block the UI thread by calling Result, the async method cannot schedule back to the UI thread to complete.

Resources