Reputation: 1059
I'm rather new to Xamarin Forms/ Visual Studio but here is my current situation. I have a Xamarin Forms project in Visual Studio with Android, iOS, and Windows Phone subprojects. I have the following function Login:
public async Task<Tuple<bool, object>> Login(LoginCredentials credentials)
{
var loginUrl = apiUrl + "/login";
var json = JsonConvert.SerializeObject(credentials);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
Debug.WriteLine("start of try block");
HttpResponseMessage response = await client.PostAsync(loginUrl, content);
Debug.WriteLine("this will not print on iOS");
string bodyStr = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
// code that does stuff with successful response
} else
{
// code that does stuff with bad response
}
} catch (Exception e)
{
Debug.WriteLine(e);
return new Tuple<bool, object>(false, e.Message);
}
}
As you can see from the Debug.WriteLine()
's, an exception is thrown on the line:
HttpResponseMessage response = await client.PostAsync(loginUrl, content);
The exception is System.NullReferenceException: Object reference not set to an instance of an object
However, this exception only occurs on iOS. Android and Windows Phone can both successfully make this request.
My first assumption was that it was Apple's ATS which would make sense since my server is just a dev instance not using https. So I pasted in
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
to the iOS project's Info.plist. Still no luck.
I also read a question elsewhere that said to make sure Visual Studio on Windows and Xamarin on the Mac are both up to date which I have made sure of as well.
Also apiUrl
is not http://localhost
I am using the IPs on my local network (since the Mac and iOS simulator are running on a different machine) which I have confirmed are correct.
If I had to guess at this point, I would say it's still something with the ATS settings not being set properly but I've been unable to confirm this. Not sure where to go from here. I'll continue to debug and add updates but any help would be very much appreciated.
As suggested by Oleg Bogdanov, my client instance is not instantiated properly only when running iOS.
Now the task becomes figuring out why this is occurring on iOS. Here is the client
initialization code. I have tried both where it currently is and where it is commented.
public class API
{
public HttpClient client = new HttpClient();
public string apiUrl = "http://myApiUrl";
public API()
{
//this.client = new HttpClient();
}
public async Task<Tuple<bool, object>> Login(LoginCredentials credentials)
{
// login function code
}
}
I'll keep debugging this and post another update when I have any new developments. As usual, any help greatly appreciated.
Upvotes: 2
Views: 2158
Reputation: 1059
I found the solution here.
I ran NuGet Install-Package Microsoft.Net.Http
to the Portable project and it is working now.
Upvotes: 1
Reputation: 1377
I don't think there is any with ATS. I have created one POC using localhost and shared local server. Please check following code which is working for my POC
For POST request
try
{
HttpClient client = new HttpClient();
var uri = new Uri("http://localhost/RegisterDevice");
string data = "{\"username\": \"ADMIN\",\"password\": \"123\"}";
var content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
response = await client.PostAsync(uri, content);
Util.HideLoading();
if (response.IsSuccessStatusCode)
{
System.Diagnostics.Debug.WriteLine(@"Success");
}
else
{
System.Diagnostics.Debug.WriteLine(@"Fail");
}
}
catch (Exception ex)
{
}
Upvotes: 0