I have a problem sending a JSON POST via HttpClient object in a MVVMCROSS solution (Xamarin). MVVMCROSS is just a Model View ViewModel framework for cross-platform e.g. Droid, iOS, Windows etc.
So the Solution is like this:
--Core (where I have my ViewModels and Services)
--Droid (Android Layout etc)
--iOS (Not used currently)
Inside the Core I have my Service classes which I initialize via IoC (Inversion of Control, something like dependency injection)
I have this awesome API which I can use via JSON Post request. The API does face recognition and sends back the 'mood' of the face (Angry, Neutral, Happy etc.)
To use this my JSON should look like this
{
"url" : "http://previews.123rf.com/images/kadettmann/kadettmann1508/kadettmann150800099/43824672-Handsome-argentinian-guy-at-beach-Stock-Photo-happy.jpg"
}
So far so good, now the POST url is : https://api.projectoxford.ai/emotion/v1.0/recognize Seems not to hard I guess!
I also need to send two headers:
Content-Type = application/json
Ocp-Apim-Subscription-Key = My super awesome secret key
If is send this JSON via POSTMAN (Chrome plugin) I get the expected result:
[
{
"faceRectangle": {
"height": 312,
"left": 563,
"top": 208,
"width": 312
},
"scores": {
"anger": 0.00000000112,
"contempt": 0.000000049,
"disgust": 0.0000000035,
"fear": 0.000000000106,
"happiness": 0.99999994,
"neutral": 0.000000000238,
"sadness": 0.00000000005,
"surprise": 0.00000000160
}
}
]
So now i'm trying to make a MVVMCROSS app for Android and iOS which sends this JSON to the server of Microsoft.
The method I use looks like this:
public async Task<bool> RestRequestSucces(string secret, string jsonSerialized)
{
bool result = false;
try
{
HttpResponseMessage response;
using (var httpClient = new HttpClient())
{
var request = new StringContent(jsonSerialized);
request.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", secret);
response = await httpClient.PostAsync(new Uri("https://api.projectoxford.ai/emotion/v1.0/recognize"), request);
result = true;
}
}
catch (Exception e)
{
string error = e.Message;
result = false;
}
return result;
}
The JsonObject to serialized looks like this:
public class URLObject
{
public string url { get; set; }
}
To serialize the object I use this
private IMvxJsonConverter serializer = Mvx.Resolve<IMvxJsonConverter>();
serializer.SerializeObject(urlObject);
But at response = await httpClient.PostAsync my code hangs. It does not go any furthur.
I call the method RestRequestSucces like this:
IRestService restService = Mvx.Resolve<IRestService>();
restService.RestRequestSucces(secret, jsonSerialized);
This all happens inside the Core project.
My AndroidManifest.xml looks like this:
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application android:label="@string/ApplicationName" android:icon="@drawable/Icon" android:theme="@style/MyTheme"></application>
</manifest>
If someone could show me how to just POST a 'simple' JSON via MVVMCROSS inside the CORE project, that would be awesome!!
HttpClienthas trouble with some TLS/SSL sites, not sure why. I usedModernHttpClientinstead and the issue is resolved, see my answer - Igoranze