Lala
Lala

Reputation: 378

HttpClient PostAsync does not return

I've seen a lot of question about this, and all points to me using ConfigureAwait(false), but even after doing so, it still doesn't returned any response. When I run the debugger, the code stops at the PostAsync and does not continue with my code. Am I doing something wrong here? Does it have to do with me calling an API via HTTPS?

Here's the code:

public async static Task<PaymentModel> AddAsync(Card card)
{
    HttpClient client = new HttpClient();

    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:", "hidden"))));

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

    var cardJson = JsonConvert.SerializeObject(card);
    var postRequest = new StringContent(cardJson, Encoding.UTF8, "application/json");
    var request = await client.PostAsync(new Uri("https://sample-3rd-party-api/api/endpoint/here"), postRequest).ConfigureAwait(false);
    var content = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
}

EDIT:

In response to the comments below, the code is contained from a method AddAsync(Card card) called from a button click with a handler:

public async void OnExecute(object sender, EventArgs args)
{
    //some code here
    payment = await PaymentModel.AddAsync(card).ConfigureAwait(false);
}

EDIT 2: I tried pinging the API, but it returns a request timed out, but when I tried it using Postman, it's doing fine (the API is just a Sandbox which is open for all, so it's okay to share this): enter image description here

enter image description here

EDIT 3:

I think the problem lies with where I don't have an SSL certificate to access the API. I have a PHP server that connects to the same API and I have to set SSL_VERIFYPEER to false just so I can access it (don't worry, I added a cacert now so its on true again). Can the same issue be happening here? If so, what can I do to create a valid certificate for my xamarin forms app

Upvotes: 14

Views: 8170

Answers (5)

Prabodha
Prabodha

Reputation: 680

I was having the same issue and below trick fixed the issue.

Change your var request = await client.PostAsync(...); as below

var task = client.PostAsync(new Uri("https://sample-3rd-party-api/api/endpoint/here"), postRequest);
var request = task.GetAwaiter().GetResult();

Upvotes: 1

Lala
Lala

Reputation: 378

So I think the problem is resolved now since I'm able to receive content from the request, what I did was simply follow the docs here: https://learn.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/transport-layer-security?tabs=windows

It looks like my settings are outdated in platform level.

Update the HttpClient implementation and SSL/TLS implementation options to enable TLS 1.2 security.

Update the HttpClient Implementation option to enable TSL 1.2 security. (NSUrlSession (iOS 7.0+)

Upvotes: 0

Erfan Mohammadi
Erfan Mohammadi

Reputation: 444

You can use this

var json = JsonConvert.SerializeObject(card);
using (var client = new HttpClient())
{
    var t = await client.PostAsJsonAsync("https://sample-3rd-party-api/api/endpoint/here", json);

    Response R =JsonConvert.DeserializeObject<Response>((JsonConvert.DeserializeObject(t.Content.ReadAsStringAsync().Result.ToString())).ToString());
}

Upvotes: 3

Debashish Saha
Debashish Saha

Reputation: 336

Does it have to do with me calling an API via HTTPS?

As you are remaining in the same network and calling the same API from POSTMAN and .NET HTTP Client and only getting success with POSTMAN.So this issue gets cancelled. Next

tried pinging the API, but it returns a request timed out

This is answered on top of mine.

Can you Please try setting the timeout option for HTTPClient while initializing.

client.Timeout = TimeSpan.FromSeconds(10);

and if still Problem persists please setup Fiddler and compare both the req sent from POstman and .NET client

Upvotes: 0

S.C.
S.C.

Reputation: 1160

What's most likely happening here is your OnExecute method has a return type of void instead of Task which prevents the UI thread from being able to await it. Try either changing that return type to Task or creating a new UI thread to perform this work. I wouldn't worry about the ping timing out as long as Postman works. Many public web servers disable their ping response.

Upvotes: 1

Related Questions