I need to post data to a webservice from my xamarin.forms application. I get a mono crash on my ipod touch when client.PostAsync is called. I don't (know how to?) get any usable crash data. One thing I notice is that even though it is an awaited async call, it does not appear to wait for a response (the response object is null) before moving on. It then crashes in the next couple of seconds. It looks like it might be that it crashes when it gets a response and tries to resume the thread.
It never hits any breakpoints, it just hard stops. I have included an example call, the post data doesn't seem to make a difference. I get the same response when I post an empty stringcontent.
I don't get the same crash in the emulator, only when it is deployed to a device. Right now and for the foreseeable future this app will only be used on an ipod, so I am happy to move the post from xamarin.forms and into the ios code if that would be preferable/more stable.
public static async Task<bool> UpdateContact(App app, string oldContactName)
{
try
{
var c = new
{
Name = app.Settings.SiteContactName,
Email = app.Settings.SiteContactEmail,
CellNumber = app.Settings.SiteContactCellPhone,
siteCode = app.Settings.SiteName,
oldContactName = oldContactName
};
await DoPost(app, "UpdateContact", c);
return true;
}
catch (Exception exc)
{
await AddLog(app, "Network Error", string.Format("There was an error updating the contact at {0}. MSG: {1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm"), exc.Message));
return false;
}
}
private static async Task DoPost(App app, string action, object data)
{
await DoPost(app.Settings.WebServiceUrl, action, data, app.BatteryLevel);
}
private static async Task DoPost(string baseUrl, string action, object data, int batteryLevel = -1)
{
var url = baseUrl + action;
var postContent = GetHttpContentFromObject(data, batteryLevel);
HttpResponseMessage response;
using (var client = new HttpClient())
{
response = await client.PostAsync(url, postContent);
}
if (response.IsSuccessStatusCode == false)
{
throw new Exception(string.Format("Could not reach web service. Code:{0} MSG:{1}", response.StatusCode, response.Content.ToString()));
}
var contentVal = await response.Content.ReadAsStringAsync();
if (contentVal != "")
{
throw new Exception(string.Format("Got an error from the web service. MSG:" + contentVal));
}
}
private static HttpContent GetHttpContentFromObject(object data, int batteryLevel = -1)
{
var kvp = new List<KeyValuePair<string, string>>();
if (data != null)
{
var props = data.GetType().GetRuntimeProperties();
if (props != null)
{
foreach (var p in props)
{
try
{
var val = p.GetValue(data);
kvp.Add(new KeyValuePair<string, string>(p.Name, (val != null ? val.ToString() : "")));
}
catch(Exception exc)
{
var e = exc;
}
}
}
kvp.Add(new KeyValuePair<string, string>("batteryLevel", batteryLevel.ToString()));
}
return new FormUrlEncodedContent(kvp);
}