I'm trying to learn about Async programming using VS2012 and its Async Await keyword. That is why i wrote this piece of code:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
string get = await GetResultsAsync("http://saskir.medinet.se");
resultsTextBox.Text = get;
}
private async Task<string> GetResultsAsync(string uri)
{
HttpClient client = new HttpClient();
return await client.GetStringAsync(uri);
}
The problem is that when i try to debug the application, it gives me an error with this message:
The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set.
I guess this is because the website have some Swedish char, but i can't find how to change the encoding of the response. Anyone can guide me plz?
You may have to check the encoding options and get the correct one. Otherwise, this code should get you going with the response.
private async Task<string> GetResultsAsync(string uri)
{
var client = new HttpClient();
var response = await client.GetByteArrayAsync(uri);
var responseString = Encoding.Unicode.GetString(response, 0, response.Length - 1);
return responseString;
}
In case you want a more generic method, following works in my UWP case in case someone has one with Unicode, would be great add the if:
var response = await httpclient.GetAsync(urisource);
if (checkencoding)
{
var contenttype = response.Content.Headers.First(h => h.Key.Equals("Content-Type"));
var rawencoding = contenttype.Value.First();
if (rawencoding.Contains("utf8") || rawencoding.Contains("UTF-8"))
{
var bytes = await response.Content.ReadAsByteArrayAsync();
return Encoding.UTF8.GetString(bytes);
}
}
WinRT 8.1 C#
using Windows.Storage.Streams;
using System.Text;
using Windows.Web.Http;
// in some async function
Uri uri = new Uri("http://something" + query);
HttpClient httpClient = new HttpClient();
IBuffer buffer = await httpClient.GetBufferAsync(uri);
string response = Encoding.UTF8.GetString(buffer.ToArray(), 0, (int)(buffer.Length- 1));
// parse here
httpClient.Dispose();
Related
it's been a while that I try to write asynchronous code in C#, I did it and was sure it is asynchronous, recently I read I checked with postman the time that the function takes to finish when it's Asynchronous and when it's synchronous, and it seems like it takes the SAME time exactly, what I did wrong in my code?
Here is my code:
[HttpGet]
[Route("customerslist")]
public async Task<IHttpActionResult> getData()
{
string url1 = #"https://jsonplaceholder.typicode.com/photos";
string url2 = #"https://jsonplaceholder.typicode.com/comments";
string url3 = #"https://jsonplaceholder.typicode.com/todos";
Task<string> firstTask = myHttpCall(url1);
Task<string> secondTask = myHttpCall(url2);
Task<string> thirdTask = myHttpCall(url3);
await Task.WhenAll(firstTask, secondTask, thirdTask);
var result = firstTask.Result + secondTask.Result + thirdTask.Result;
return Ok(result);
}
private async Task<string> myHttpCall(string path)
{
string html = string.Empty;
string url = path;
// Simple http call to another URL to receive JSON lists.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
return html;
}
I make HTTP request to another URL to get their JSON lists, anyone can help me please? I will be happy if anyone can tell me how to write it properly.
Your HTTP calls are synchronous. Use HttpClient in your myHttpCall method more or less like this:
private async Task<string> myHttpCall(string path)
{
using(HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(path);
return await response.Content.ReadAsStringAsync();
}
}
EDIT: To add automatic decompression pass following object to HttpClient constructor:
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip
};
I am doing HTTP get request using HttpClient in C# console app . I am not getting expected response with one get request.
Get Request is like
http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk
I am getting some vague response but when i do same get request with fiddler it is giving expected response.
How can I get expected response from httpClient.GetAsync(url)?
code is :-
var httpClient = new HttpClient();
var url = "http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk";
HttpResponseMessage response1 = await httpClient.GetAsync(url);
if (response1.IsSuccessStatusCode)
{
HttpContent stream = response1.Content;
Task<string> data = stream.ReadAsStringAsync();
}
You should read as string that way:
string result = await stream.ReadAsStringAsync();
instead of that:
Task<string> data = stream.ReadAsStringAsync();
Here full code example and another example
This is a full method using async/await approach.
private static async Task<string> GetRequestContentAsString(string url)
{
var data = string.Empty;
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stream = response.Content;
data = await stream.ReadAsStringAsync();
}
}
return data;
}
This method is called this way:
var content = await GetRequestContentAsString("http://www.bing.com");
i have the following problem, i try to wait for for an Async Web Response.
But it never finished.
public string getTermine(string trmId)
{
System.Threading.Tasks.Task<string> lisi = LoadTermine((HttpWebRequest)WebRequest.Create("http://" + curent.usrCH + apiKey + curent.phrase + apiTrmIDIS + trmId));//Request get String result like http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start="+i+"&q=
lisi.Wait();
return lisi.Result;
}
private async System.Threading.Tasks.Taskstring>LoadTermine(HttpWebRequest myRequest)
{
//List<Termine> terminListe = new List<Termine>();
List<Appointment> Resu = null;
using (WebResponse response = await myRequest.GetResponseAsync())
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream()))
{
Resu = reader.ReadToEnd();
}
}
return Resu;
}
P.S. I cant use and synchronous request because this methods are an part of the Base code which is used by iOS, WinPhone and Android and i dont know why i cant get an synchronous WebResponse.
You are creating a deadlock by calling .Result on the task.
You could do something like this where the remoteUrl variabled is the url of your web service
private async System.Threading.Tasks.Task<string> LoadTermineAsync(HttpWebRequest myRequest)
{
using (var client = new HttpClient()) {
using (var request = new HttpRequestMessage(HttpMethod.Get, myRemoteUrl)) {
var response = await client.SendAsync(request).ConfigureAwait(false);
var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return result;
}
}
}
For more info on Async/Await
And this evolve video is a little bit more advanced.
I am making uwp(Universal Windows Platform) application and want to deserialize this xml: http://radioa24.info/ramowka.php to object, but I got instead for scpecial characters as ł, ó some strange letters and special ones like: \n and \r:
"Ä…"=>"ą"
"ć"=>"ć"
"Ä™"=>"ę"
For example instead of Poniedziałek i got PoniedziaÅ\u0082ek
My code:
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(uri).AsTask();
response.EnsureSuccessStatusCode();
var result = await httpResponse.Content.ReadAsStringAsync();
I was trying to make some Encoding convertions but nothing worked out.
How to solve it because later I want to got my object?
var reader = new XmlSerializer(typeof(Sources.Schedule));
using (var tr = new MemoryStream(Encoding.UTF8.GetBytes(resultString)))
{
Schedule = (Sources.Schedule)reader.Deserialize(res);
}
Please can you try the code below, reading data as bytes solves your issue.
using (HttpClient client = new HttpClient())
{
Uri url = new Uri("http://radioa24.info/ramowka.php");
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, url);
Task<HttpResponseMessage> responseAsync = client.SendRequestAsync(httpRequest).AsTask();
responseAsync.Wait();
responseAsync.Result.EnsureSuccessStatusCode();
Task<IBuffer> asyncBuffer = responseAsync.Result.Content.ReadAsBufferAsync().AsTask();
asyncBuffer.Wait();
byte[] resultByteArray = asyncBuffer.Result.ToArray();
string responseString = Encoding.UTF8.GetString(resultByteArray, 0, resultByteArray.Length);
responseAsync.Result.Dispose();
}
As Jon Skeet notes in his answer this should be fixed on the server. If you check the server sends back the following Content-Type header:
Content-Type: text/xml
It should tell you the encoding (Content-Type: text/xml; charset=utf-8), that's why it should be a server fix.
But if you are sure that this is UTF-8 (it is, because the response xml contains <?xml version="1.0" encoding="UTF-8"?>), you can do this:
var httpClient = new HttpClient();
var response = await httpClient.GetBufferAsync(uri);
var bytes = response.ToArray();
var properEncodedString = Encoding.UTF8.GetString(bytes);
Here is my example that works fine with Polish words.
Method to get xml from page:
public async Task<string> GetXMl(string uri)
{
string result = null;
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
return result;
}
Method to deserialize xml:
public void DeserializeXml(string xml)
{
var serializer = new XmlSerializer(typeof(ramowka));
var buffer = Encoding.UTF8.GetBytes(xml);
using (var stream = new MemoryStream(buffer))
{
var ramowka = (ramowka)serializer.Deserialize(stream);
}
}
Example how to use methods, for example in button click event:
private async void Button_Click(object sender, RoutedEventArgs e)
{
string xml = await GetXMl("http://radioa24.info/ramowka.php");
DeserializeXml(xml);
}
Also here you are converted by Visual Studio xml to C# classes
http://pastebin.com/aJ4B1aCF
I'm executing an async POST request using a HttpClient in C#/Xamarin:
private async Task<string> ServicePostRequest (string url, string parameters)
{
string result = String.Empty;
using (var client = new HttpClient()) {
HttpContent content = new StringContent (parameters);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue ("application/x-www-form-urlencoded");
client.Timeout = new TimeSpan (0, 0, 15);
using(var response = await client.PostAsync(url, content)){
using (var responseContent = response.Content) {
result = await responseContent.ReadAsStringAsync ();
Console.WriteLine (result);
return result;
}
}
}
}
When I execute the following code, the expected result (JSON) is being logged correctly in the terminal:
Task<string> result = ServicePostRequest("http://www.url.com", "parameters");
Now, I would like to get this result into a variable to be able to parse it. However, when I use the following code, no result is being logged at all and the application is frozen:
Task<string> result = ServicePostRequest("http://www.url.com", "parameters");
string myResult = result.Result;
Also when I use the result.Wait() method, the application doesn't respond at all.
Any help would be highly appreciated.
Since ServicePostRequest is an awaitable method, change this:
Task<string> result = ServicePostRequest("http://www.url.com", "parameters");
string myResult = result.Result;
To:
string result = await ServicePostRequest("http://www.url.com", "parameters");
Side Note: Make sure the calling method is an Asynchronous method.