why await does not wait untill httpclient postasync complets? - c#

Im creating http client for consume some api.
Here is my client method calling to api endpoint.
public async Task<HttpResponseMessage> SendRequestAsync()
{
string adaptiveUri = "https://some-api/api/Authentication/AuthenticateThirdPartyUserAsync";
using (HttpClient httpClient = new HttpClient())
{
var json = JsonConvert.SerializeObject(new { userName = "uname", password = "123", applicantCode = "hello" });
var payload = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage responseMessage = null;
try
{
responseMessage = await httpClient.PostAsync(adaptiveUri, payload);
}
catch (Exception ex)
{
if (responseMessage == null)
{
responseMessage = new HttpResponseMessage();
}
responseMessage.StatusCode = HttpStatusCode.InternalServerError;
responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
}
return responseMessage;
}
}
calling method is as follows
public async Task<IBaseStatus> Handle(InspectionAddedEvent domainEvent)
{
var tk = await _iAClient.SendRequestAsync();
return something;
}
but await does not wait untill postasync completes.
but when i use
httpClient.PostAsync(adaptiveUri, payload).GetAwaiter().GetResult()
it waits until post is complets.
can anyone have idea about this?
Thanks.

await _iAClient.SendRequestAsync(); definitely waits for the PostAsync.
I think the problem is that your are receiving an exception in SendRequestAsync and confuse the result.
Remove completely the try/carch block
public async Task<HttpResponseMessage> SendRequestAsync()
{
string adaptiveUri ="https://someapi/api/Authentication/AuthenticateThirdPartyUserAsync";
using (HttpClient httpClient = new HttpClient())
{
var json = JsonConvert.SerializeObject(new { userName = "uname", password = "123", applicantCode = "hello" });
var payload = new StringContent(json, Encoding.UTF8, "application/json");
return await httpClient.PostAsync(adaptiveUri, payload);
}
}
And try to catch it in the caller:
public async Task<IBaseStatus> Handle(InspectionAddedEvent domainEvent)
{
try
{
var tk = await _iAClient.SendRequestAsync();
return something;
}
catch(Exception ex)
{
//Probably return some IBaseStatus
}
}

Related

HttpClient.SendAsync() returns status code 200 even if the remote server is down

A simple login method that works just fine until I shut down my API. Then the try-catch block acts as intended, and an exception is thrown and caught but, _response comes out with a status code of "200, OK". For the love of me, I can't figure out why. Please help!
The code looks so bad mainly because of all the patching and testing I am doing on it to figure out what is happening.
HttpResponseMessage response = null;
public async Task<HttpResponseMessage> login(AuthModel model)
{
HttpResponseMessage response = null;
model.responseMessage = "";
var client = new HttpClient();
string text = "{\"email\": \""+model.email+"\",\"password\": \""+model.password+"\"}";
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(_baseURL+"/api/user/login"),
Content = new StringContent(text, Encoding.UTF8, "application/json")
};
try
{
using (response = await client.SendAsync(request))
{
HttpResponseMessage _response = null;
//response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
//_response = response;
var body = await response.Content.ReadAsStringAsync();
var token = response.Headers.GetValues("auth-token").FirstOrDefault();
model.authToken = token;
model.name = body;
model.responseMessage = "Congratulations!";
return _response;
}
else
{
model.name = "";
model.responseMessage = await response.Content.ReadAsStringAsync();
return _response;
}
}
}
catch(Exception e) {
// model.responseMessage = e.Message;
return _response;
}
}
using "HttpResponseMessage _response = new HttpResponseMessage();" was setting the _response.StatusCode to be as "200" and the code was not dealing with that.

API Works in Postman but while hitting from code no response is generated

I have Get API for getting data, when it is hitting from Postman it gives response properly,
but while hitting from the code it skipping the code. I am using HttpClient().
My code for hitting the api is below :
I didn't get the point here why this happening.
public async Task<string> GetAsync(string uri, string serverAddress = "")
{
try
{
string id = System.DateTime.Now.ToString("hhmmss");
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 0, 0, Timeout);
httpClient.BaseAddress = new Uri(serverAddress);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var responseMessage = await httpClient.GetAsync(new Uri(uri));
var responseContent = await responseMessage.Content.ReadAsStringAsync();
if (!responseMessage.IsSuccessStatusCode)
{
throw new RestException
{
ResponseCode = (int)responseMessage.StatusCode,
ResponseContent = responseContent
};
}
return responseContent;
}
catch (Exception ex)
{
throw new Exception($"The Get request timed out. Exception :- {ex.Message}");
}
}
From this line -->
var responseMessage = await httpClient.GetAsync(new Uri(uri));
my code is skipping
Edit -->
After Testing more, I also got no exception after the timeout.
comment below line in your code
httpClient.BaseAddress = new Uri(serverAddress);
and pass full url instead of new Uri(uri) in below line
var responseMessage = await httpClient.GetAsync(new Uri(uri));
Try the following:
public async Task<string> GetAsync(string uri, string serverAddress = "")
{
try
{
string id = System.DateTime.Now.ToString("hhmmss");
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 0, 0, Timeout);
httpClient.BaseAddress = new Uri(serverAddress);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var responseMessage = await httpClient.GetAsync(uri);
var responseContent = await responseMessage.Content.ReadAsStringAsync();
if (!responseMessage.IsSuccessStatusCode)
{
throw new RestException
{
ResponseCode = (int)responseMessage.StatusCode,
ResponseContent = responseContent
};
}
return responseContent;
}
catch (Exception ex)
{
throw new Exception($"The Get request timed out. Exception :- {ex.Message}");
}
}
Ensure you add await before calling this method in your code and check if the full URL that's actually called has been build correctly. You can just pass a string into the GetAsync() method, no need to create a new URI.

HttpClient.PostAsJsonAsync crushed without exception

I am trying to call an api(POST method) with HttpClient.PostAsJsonAsync. However, it stopped at httpClient.PostAsJsonAsync without any exception.
The source code as below:
public static async Task<oResult> PostApi(string JSON_sObject, string sEnd_Url) {
oResult oResult = new oResult();
var Data = JsonConvert.DeserializeObject(JSON_sObject);
var Url = "http://localhost:44340/" + sEnd_Url;
HttpClient httpClient = new HttpClient();
try {
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await httpClient.PostAsJsonAsync(new Uri(Url), Data); // it stopped here
if (response.IsSuccessStatusCode)
{
var sResponse_content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<oResult>(sResponse_content);
}
else
{
return oResult;
}
}
catch (Exception ex)
{
LogFile(ex);
return oResult;
}
}
Please advice me if any issue from the source code.
Thank you
you should not trying serialize deserialize twice
remove from your code
var Data = JsonConvert.DeserializeObject(JSON_sObject);
and replace
HttpResponseMessage response = await httpClient.PostAsJsonAsync(new Uri(Url), Data);
with this
var content = new StringContent(JSON_sObject, Encoding.UTF8, "application/json");
var response = await client.PostAsync(sEnd_Url, content);
also fix base httpclient address
var baseUri= #"http://localhost:44340";
using HttpClient client = new HttpClient { BaseAddress = new Uri(baseUri) };
try {

Xamarin PostAsync giving No Content Resposne

I am doing this function in Xamarin Forms:
public async Task<HttpResponseMessage> RegisterClient(string url)
{
try
{
using (HttpClient httpclient1 = new HttpClient())
{
var newClient = new Client()
{
CountryId = 223,
Email = "somename#123.com",
Fname = "From Xamarin",
UserName = "somename",
Dob = Convert.ToDateTime("2020-01-01"),
Password = "SomeSome"
};
var jsonObject = JsonConvert.SerializeObject(newClient);
HttpContent content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpclient1.PostAsync(url, content);
return response;
}
}
catch (Exception ex)
{
await DisplayAlert("Information", ex.Message, "Ok");
return null;
}
}
This code function is returning No Content even after assigning values. Any clue where i am wrong. WebAPI is working fine in POSTMAN. My WebAPI Controller looks like this:
[HttpPost("PostClient")]
public async Task<ActionResult<Client>> PostClient(Client client)
{
try
{
_context.Clients.Add(client);
await _context.SaveChangesAsync();
return CreatedAtAction("GetClient", new { id = client.ClientId }, client);
}
catch(Exception ex)
{
return null;
}
}
Please help. Thank you
Resolved.
HttpClient httpClient = new HttpClient();
Uri uri = new Uri(url);
StringContent content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, content);
httpResponseMessage.EnsureSuccessStatusCode();
var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine(httpResponseBody);
Replaced Encoding.UTF8 to UnicodeEncoding.UTF8 and it worked. Mystery solved.

System.Net.Http.HttpClient in [Universal Windows Platform] not working properly

I wrote simple method for getting data from (online) REST Service:
public async Task<Object> GetTask()
{
try
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://111.111.111.111:8080/");
HttpResponseMessage result = await client.GetAsync("ABC/CDE/getsomeinfo");
if (result.IsSuccessStatusCode)
{
//Deserialize
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Error" + ex);
}
return null;
}
Whenever i run this on UWP i'm getting catch exception:
The text associated with this error code could not be found.
A connection with the server could not be established
HResult 2147012867
Im trying to connect my client with restapi in internal network. In forms same code is working properly.
Try this
HttpResponseMessage response;
public async Task<string> webserviceResponse(string HttpMethod)
{
// check internet connection is available or not
if (NetworkInterface.GetIsNetworkAvailable() == true)
{
// CancellationTokenSource cts = new CancellationTokenSource(2000); // 2 seconds
HttpClient client = new HttpClient();
MultipartFormDataContent mfdc = new MultipartFormDataContent();
mfdc.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
string GenrateUrl = "your url";
if (HttpMethod == "POST")
{
response = await client.PostAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "PUT")
{
response = await client.PutAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "GET")
{
response = await client.GetAsync(GenrateUrl);
}
var respon = await response.Content.ReadAsStringAsync();
string convert_response = respon.ToString();
return convert_response;
}
else
{
return "0";
}
}

Categories

Resources