HttpClient.PostAsJsonAsync crushed without exception - c#

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 {

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.

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.

How to pass request content with HttpClient GetAsync method in c#

How do I pass request content in the HttpClient.GetAsync method? I need to fetch data depending upon request content.
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch()
{
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch");
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
If you are using .NET Core, the standard HttpClient can do this out-of-the-box. For example, to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
If you want to send content, then you need to send it as query string (According to your API route)
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch/paramname=<dynamicName>&paramValue=<dynamicValue>");
And in API check for "paramName" and "paramValue"
this works for me:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("your url"),
Content = new StringContent("your json", Encoding.UTF8, ContentType.Json),
};
using (var response = await httpClient.SendAsync(request))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
}
EDITED:
This is minor different then #SonaliJain answer above:
MediaTypeNames.Application.Json instead of ContentType.Json
I'm assuming that your "request content" would be POST data, no?
If you're sending it using the standard form content way of doing it, you would first have to build the content:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "theperplexedone"),
new KeyValuePair<string, string>("password", "mypassword123"),
});
And then submit it using PostAsync instead:
var response = await client.PostAsync("http://localhost:8080/document/quicksearch", content);
Hi all thank you for your comments, i got the solution
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch(HttpRequestMessage Query)
{
Debugger.Launch();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
Console.WriteLine(Query);
HttpResponseMessage response = await client.GetAsync("http://localhost:8080/document/quicksearch/"+ Query.RequestUri.Query);
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
{
Console.Write("Failure");
}
return response;
}
}
catch (Exception e)
{
throw e;
}

How to post JSON with HttpClient using C#?

I have no idea how to POST JSON with HttpClient. I find some solution, like this, but I have to use HttpClient, cause of async and have to add a header.
This is my code below. Any idea how to fix it?
List<Order> list = new List<Order> { new Order() { Name = "CreatedTime", OrderBy = 1 } };
Queues items = new Queues { Orders = list };
var values = new Dictionary<string, string> { { "Orders", JsonConvert.SerializeObject(list) } };
var content = new FormUrlEncodedContent(values);
//HttpContent cc = new StringContent(JsonConvert.SerializeObject(items));
_msg = await _client.PostAsync(input, content);
//_msg = await _client.PostAsync(input, cc);
var response = await _msg.Content.ReadAsStringAsync();
You can use the method PostAsJsonAsync which can be found in the extensions assemblies:
System.Net.Http.Formatting.dll
Example
public static async Task SendJsonDemo(object content)
{
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync("https://example.com", content);
}
}
If you want to add custom headers to the request, add it to DefaultRequestHeaders:
client.DefaultRequestHeaders.Add("mycustom", "header1");
You can send any type of request like as
public static async Task<HttpResponseMessage> SendRequest(HttpMethod method, string endPoint, string accessToken, dynamic content = null)
{
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(method, endPoint))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
if (content != null)
{
string c;
if (content is string)
c = content;
else
c = JsonConvert.SerializeObject(content);
request.Content = new StringContent(c, Encoding.UTF8, "application/json");
}
response = await client.SendAsync(request).ConfigureAwait(false);
}
}
return response;
}

Categories

Resources