HttpClient fails to initialize - c#

After running with the debugger this line of code
HttpClient client = new HttpClient()
the application suddenly exits. Anybody have some ideas why this appears?
This is the code:
static void Main(string[] args)
{
Task.Run(() => translate("en", "bg", "hello").Wait());
}
static async Task translate(string sourceLang, string targetLang, string sourceText)
{
string page = "http://www.transltr.org/api/translate?text=" +
sourceText + "&to=" + targetLang + "&from=" + sourceLang;
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(page);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
string trans = await response.Content.ReadAsStringAsync();
Console.WriteLine(trans);
Console.ReadLine();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
and it stops executing after this line
HttpClient client = new HttpClient()

Task.Run(() => translate("en", "bg", "hello")).Wait();
Code is working, with a small adjustment you need to await task created at Task.Run

Related

How to have an API call working? Currently my call to client is not working

I have an API in .net 5 that runs locally. One of the endpoints is https://localhost:44362/User
Now, I created a console app that will consume the API and defined a method to call the get User.
public async Task<bool> CallAPI()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:44362/");
using (HttpResponseMessage response = await client.GetAsync("User"))
{
var resContent = response.Content.ReadAsStringAsync().Result;
return true;
}
}
}
Here is the code in the API
[HttpGet]
public IEnumerable<User> Get()
{
using (var context = new ohabartContext())
{
return context.Users.ToList();
}
}
But when the code using (HttpResponseMessage response = await client.GetAsync("User")) is executed nothing happens. I don't receive any error or whatsoever. I search the net and all other codes look the same in consuming or calling an API.
What seems to be the problem?
ReadAsStringAsync() Serialize the HTTP content to a string as an asynchronous operation. This operation will not block. The returned Task object will complete after all of the content has been written as a string.
HttpResponseMessage response= await client.GetAsync(u);
var resContent = await response.Content.ReadAsStringAsync().Result;
Once the operation completes, the Result property on the returned task object contains the string with the HTTP content.
public async Task<bool> CallAPI()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:44362/");
HttpResponseMessage response = await client.GetAsync(u);
var resContent = awit response.Content.ReadAsStringAsync().Result;
return true;
}
}
catch (HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} " , e.Message);
return false;
}
}
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getasync?view=net-6.0

HttpClient.PostAsync crash app. How to catch the Exception?

I'm trying to test this HttpRequest:
public void TestX(string baseUrl)
{
StringContent httpContentDistanza = new StringContent(GlobalVariables.JsonDistanza);
using HttpClient httpClient = new HttpClient
{
BaseAddress = new Uri(baseUrl)
};
HttpResponseMessage responseMessage = null;
try
{
responseMessage = httpClient.PostAsync("/xxx/xx/xxx", httpContentDistanza).Result;
// can't reach the code below
if (responseMessage.IsSuccessStatusCode)
{
string strContext = responseMessage.Content.ReadAsStringAsync().Result;
var risultato = JsonSerializer.Deserialize<Distanza1>(strContext);
GlobalVariables.DblAijCrnPsz = risultato.data.processDataIn.valore;
}
}
catch (Exception ex)
{
if (responseMessage == null)
{
responseMessage = new HttpResponseMessage();
}
responseMessage.StatusCode = HttpStatusCode.InternalServerError;
responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
}
}
The problem is that the URI is not reachable, and I was expecting that its gonna throw some Exception, but it did not.
In case where URI is not reachable I need some how to catch that Exception.
I'm using BackgroundWorker to run TestX():
public MainWindow()
{
InitializeComponent();
bgWorker = new BackgroundWorker { WorkerReportsProgress = true };
bgWorker.DoWork += ResetAll;
}
private void ResetAll(object sender, DoWorkEventArgs e)
{
var x = gestLink.TestX(GlobalVariables.BaseUrl).ToString();
//it also does't reach the code below
....
}
Update
I don't know what I'm doing wrong.. I still can't catch the exception :
public async Task TestX(string baseUrl)
{
StringContent httpContentDistanza = new StringContent(GlobalVariables.JsonDistanza);
using HttpClient httpClient = new HttpClient
{
BaseAddress = new Uri(baseUrl)
};
HttpResponseMessage responseMessage = null;
try
{
responseMessage = await client.PostAsync("/xxx/xxx/xx", httpContentDistanza);
if (responseMessage.IsSuccessStatusCode)
{
string strContext = await responseMessage.Content.ReadAsStringAsync();
var risultato = JsonSerializer.Deserialize<Distanza1>(strContext);
}
}
catch(Exception ex)
{
var error = ex.Message;
}
It crash here responseMessage = await httpClient.PostAsync("/xxx/xx/xxx", httpContentDistanza); but stops in ResetAll() and var x = this.
I have seen and read similar problems (Debugger stops after async HttpClient.GetAsync() and HttpClient.PostAsync and await crashing app) before, but no solutions have helped me.
Any suggestions how to catch the exception?
You should change this:
public void TestX(string baseUrl)
to
public async Task TestX(string baseUrl)
and this
responseMessage = httpClient.PostAsync("/xxx/xx/xxx",httpContentDistanza).Result;
to
responseMessage = await httpClient.PostAsync("/xxx/xx/xxx", httpContentDistanza);
Then you can handle Exceptions.

Invoking an async function from a sync function

I have a function in a c# console application, which calls an async function (My aim is to call an azure function via a console application. This function is responsible for converting zip files to csv files and of course I would like to process the zip file in parallel)
Here you can find a section of my code:
Parallel.ForEach(blobs, (currentblob) =>
{
string FileUrl = currentblob.Uri.ToString();
string FileName = currentblob.Uri.Segments.Last();
//string content = "{ \"fileUri\": \""+ currentblob.Uri.ToString()+ "\" , \"fileName\": \""+ currentblob.Uri.Segments.Last()+"\"}";
Console.WriteLine(currentblob.Uri + " #### " + currentblob.Uri.Segments.Last());
var values = new Dictionary<string, string>
{
{ "fileUri", currentblob.Uri.ToString() },
{ "fileName", currentblob.Uri.Segments.Last() }
};
var content = new FormUrlEncodedContent(values);
string baseURL = #"https://<afu>.azurewebsites.net/api/process_zip_files_by_http_trigger?code=45"; ;
//string urlToInvoke = string.Format("{0}&name={1}", baseURL, FileUrl, FileName);
Run(baseURL, content);
});
And I have an async function:
public static async void Run(string i_URL,FormUrlEncodedContent content)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(i_URL,content);
string responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Console.ReadLine();
}
I can run my code without any errors, but it doesn't process zip files. But after I stop debugging then I it starts to process the files!!!
I think something is wrong with my async function. Do you have any idea why my code doesn’t work correctly? Do I call my async function correctly?
First, your calling an async void method, these methods provide no way of signalling completion and are only intended for event handlers. Second, to process async methods in parallel you use Task.WhenAll with a Select instead of Parallel.ForEach. Parallel.ForEach is only intended for CPU bound operations and not asynchronous tasks. Finally, you should then use async all the way up to the root of your application and await all results, this will keep your process alive until all your blobs have been handled.
class Program
{
private static HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
var blobs = new List<Blob>();
await ProcessBlobs(blobs);
Console.ReadLine();
}
public static async Task ProcessBlobs(IEnumerable<Blob> blobs)
{
var tasks = blobs.Select(currentblob =>
{
string FileUrl = currentblob.Uri.ToString();
string FileName = currentblob.Uri.Segments.Last();
//string content = "{ \"fileUri\": \""+ currentblob.Uri.ToString()+ "\" , \"fileName\": \""+ currentblob.Uri.Segments.Last()+"\"}";
Console.WriteLine(currentblob.Uri + " #### " + currentblob.Uri.Segments.Last());
var values = new Dictionary<string, string>
{
{ "fileUri", currentblob.Uri.ToString() },
{ "fileName", currentblob.Uri.Segments.Last() }
};
var content = new FormUrlEncodedContent(values);
string baseURL = #"https://<afu>.azurewebsites.net/api/process_zip_files_by_http_trigger?code=45"; ;
//string urlToInvoke = string.Format("{0}&name={1}", baseURL, FileUrl, FileName);
return RunAsync(baseURL, content);
});
await Task.WhenAll(tasks);
}
public static async Task RunAsync(string i_URL, FormUrlEncodedContent content)
{
var response = await client.PostAsync(i_URL, content);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
}
}

call REST API in xamarin

I design a login form in xamarin Form PCL and I want to call a my webservice that will return JSON. For this, I created two functions for the same but both are n is not returning values.
Can you please tell me what I am doing wrong?
async void OnLoginButtonClick(object sender, EventArgs e)
{
if (usernameEntry.Text != "" && passwordEntry.Text != "")
{
var response = GetLoginDetails(usernameEntry.Text,passwordEntry.Text);
var getData = await getDataFromService(usernameEntry.Text, passwordEntry.Text);
}
}
public static async Task<HttpResponseMessage> GetLoginDetails(string username, string password)
{
try
{
var httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://mywebserverIP/api/Users?Username=" + username + "&Password=" + password);
var response = await httpClient.SendAsync(request);
return response;
}
catch (Exception ex)
{
throw;
}
}
public static async Task<dynamic> getDataFromService(string username, string password)
{
using (var client = new HttpClient())
{
var responseText = await client.GetStringAsync("http://mywebserverIP/api/Users?Username=" + username + "&Password=" + password);
dynamic data = JsonConvert.DeserializeObject(responseText);
return data;
}
}
Thanks for your comment in Advance.
As you not awaiting the first method , request thread will not wait till it returns the value so , 1st change you have to make is to
var response = await GetLoginDetails()
For the second method
var getData = await getDataFromService()
I do not see any issue. I am not sure how you know that this method is not returning any values. Better to log the response of the both the method call and check.
Use await.
First in the
var response = await GetLoginDetails(...
then maybe in the deserializeobject method too (this one i'm not sure)
dynamic data = await Task.Run(() => JsonConvert.DeserializeObject(responseText));

HttpClient.SendAsync method exits without throwing exception

I am calling the following function to get access token for retrieving Twitter user profile using REST Api.
public async Task<string> GetAccessToken()
{
try
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token ");
var customerInfo = Convert.ToBase64String(new UTF8Encoding().GetBytes(OAuthConsumerKey + ":" + OAuthConsumerSecret));
request.Headers.Add("Authorization", "Basic " + customerInfo);
request.Content = new StringContent("grant_type=client_credentials", Encoding.UTF8, "application/x-www-form-urlencoded");
//program exits at this point
HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
string json = await response.Content.ReadAsStringAsync();
var serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(json);
return item["access_token"];
}
catch (Exception ex)
{
MessageBox.Show("In Retrieving access token : " + ex.ToString());
}
}
The program exits/terminates without retrieving a response at the point HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false); is called.
This is the parent function which calls GetAccessToken()
public async Task getUserProfile(string userName)
{
try
{
if (accessToken == null)
{
accessToken = await GetAccessToken().ConfigureAwait(false);
}
var request = new HttpRequestMessage(HttpMethod.Get, string.Format(" https://api.twitter.com/1.1/users/show.json?screen_name={0}", userName));
request.Headers.Add("Authorization", "Bearer " + accessToken);
var httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
var jsonString = await response.Content.ReadAsStringAsync();
var serializer = new JavaScriptSerializer();
dynamic jsonObj = serializer.Deserialize<object>(jsonString);
}
catch (Exception ex)
{
if (DEBUG)
{
MessageBox.Show("In Retrieving user profile from twitter : " + ex.ToString());
}
}
}
I am unable to catch an exception as to why the program exits at GetAccessToken() or getUserProfile(). But the code executes successfully and retrieves an HttpResponseMessage if getUserProfile() has Task<IEnumerable<string>> as return type. Why does this problem occur? How can the exception be caught?
Your application exits permaturely because you are not waiting for getUserProfile() to be completed. You can mark getTwitterInfo as async similar to the others or tell it to wait for the task to finish
public async Task getTwitterInfo() {
var twitter = new Twitter("consumerKey","consumerSecret");
await twitter.getUserProfile(userName);
}
OR
public void getTwitterInfo() {
var twitter = new Twitter("consumerKey","consumerSecret");
var task = twitter.getUserProfile(userName);
var result = task.WaitAndUnwrapException();
}
Have you tried
HttpResponseMessage response = httpClient.SendAsync(request).Result;
I have the same problem in my own code and this seems to have fixed it, should be equivalent to the original call. I still don't understand the root cause of the crash, though.

Categories