279

I'm trying to get content of HttpResponseMessage. It should be: {"message":"Action '' does not exist!","success":false}, but I don't know, how to get it out of HttpResponseMessage.

HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync("http://****?action=");
txtBlock.Text = Convert.ToString(response); //wrong!

In this case txtBlock would have value:

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Vary: Accept-Encoding
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Date: Wed, 10 Apr 2013 20:46:37 GMT
  Server: Apache/2.2.16
  Server: (Debian)
  X-Powered-By: PHP/5.3.3-7+squeeze14
  Content-Length: 55
  Content-Type: text/html
}
0

10 Answers 10

561

I think the easiest approach is just to change the last line to

txtBlock.Text = await response.Content.ReadAsStringAsync(); //right!

This way you don't need to introduce any stream readers and you don't need any extension methods.

Sign up to request clarification or add additional context in comments.

6 Comments

Not sure why this isn't the accepted answer, especially since this gives you the ability to easily serialize contents into your objects.
ReadAsStringAsync does not handle errors well IMHO.
You could also use Response.Content.ReadAsStringAsync().Result instead of using await
Beware though: ReadAsStringAsync() can throw if you have emoticons or some other Unicode characters in the response. I had to use Streams (like in the accepted answer) to overcome that.
@Justin don't use the result property of an async method, await it all the way up. Result property can cause deadlocks learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/…
|
78

You need to call GetResponse().

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();

7 Comments

Thanks, but why i get this error here: "System.Net.Http.HttpResponseMessage' does not contain a definition for 'GetResponseStream' and no extension method 'GetResponseStream' accepting a first argument of type 'System.Net.Http.HttpResponseMessage' could be found"
@Klemzy - Because you are calling it Asynchronisly. Try using Content property instead. Look at the example here. Scroll down to the second step.
@Klemzy - Look at the example here. Scroll down to the second step. If you can't figure it out, I'll edit my answer and give you an example for you
This answer is totally off-topic, the OP is using HttpClient, not HttpWebRequest / HttpWebResponse.
The question is in regard to HttpCient, your response is based on outdated and obsolete HttpWebRequest.
|
43

Try this, you can create an extension method like this:

    public static string ContentToString(this HttpContent httpContent)
    {
        var readAsStringAsync = httpContent.ReadAsStringAsync();
        return readAsStringAsync.Result;
    }

and then, simple call the extension method:

txtBlock.Text = response.Content.ContentToString();

I hope this help you ;-)

2 Comments

By far the easiest to get up and running
Please use await instead of .Result... or use a synchronous HTTP client instead, if your code can't handle async programming. But any modern code should, otherwise it may be a sign your application is doing something wrong.
17

If you want to cast it to specific type (e.g. within tests) you can use ReadAsAsync extension method:

object yourTypeInstance = await response.Content.ReadAsAsync(typeof(YourType));

or following for synchronous code:

object yourTypeInstance = response.Content.ReadAsAsync(typeof(YourType)).Result;

Update: there is also generic option of ReadAsAsync<> which returns specific type instance instead of object-declared one:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();

2 Comments

object yourTypeInstance = await response.Content.ReadAsAsync(typeof(YourType)); should be var yourTypeInstance = await response.Content.ReadAsAsync<YourType>();
I used Request.Content.ReadAsAsync to parse Json and got horrible performance.
8

By the answer of rudivonstaden

txtBlock.Text = await response.Content.ReadAsStringAsync();

but if you don't want to make the method async you can use

txtBlock.Text = response.Content.ReadAsStringAsync();
txtBlock.Text.Wait();

Wait() it's important, becаuse we are doing async operations and we must wait for the task to complete before going ahead.

2 Comments

using .Result any different?, httpContent.ReadAsStringAsync().Result
.Result would block the thread's execution on that line... where as txtBlock.Text.Wait() blocks on the wait() call... so you're correct that basically there is no difference. But I suspect txtBlock.Text.Wait() would take a optional integer parameter so the GUI does not hang if the previous ReadAsStringAsync() call never returns. For example the following would block for no more than 1 second txtBlock.Text.Wait(1000)
7

The quick answer I suggest is:

response.Result.Content.ReadAsStringAsync().Result

7 Comments

Do NOT call Result on tasks. You risk locking up your application. Use async/await instead.
I would not say never... sometimes quick and dirty gets it done. But I agree you do run the risk of ReadAsStringAsync() not returning, so make sure not to call it on your GUI or main application thread.
Good or almost good. I needed to code like this: HttpResponseMessage response = ....; var responseBody = await response?.Content.ReadAsStringAsync();
It's generally bad practice to call .Result on a task, you'll block the main thread.
Doesn't calling await implicitly block the main thread too? I.e. the same as getting .Result
|
2

I think the following image helps for those needing to come by T as the return type.

enter image description here

Comments

2

Updated answer as of 2022-02:

var stream = httpResponseMessage.Content.ReadAsStream();
var ms = new MemoryStream();
stream.CopyTo(ms);
var responseBodyBytes = ms.ToArray();

Comments

0

You can use the GetStringAsync method:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);

Comments

0

Using block:

using System;
using System.Net;
using System.Net.Http;

This Function will create new HttpClient object, set http-method to GET, set request URL to the function "Url" string argument and apply these parameters to HttpRequestMessage object (which defines settings of SendAsync method). Last line: function sends async GET http request to the specified url, waits for response-message's .Result property(just full response object: headers + body/content), gets .Content property of that full response(body of request, without http headers), applies ReadAsStringAsync() method to that content(which is also object of some special type) and, finally, wait for this async task to complete using .Result property once again in order to get final result string and then return this string as our function return.

static string GetHttpContentAsString(string Url)
    {   
        HttpClient HttpClient = new HttpClient();
        HttpRequestMessage RequestMessage = new HttpRequestMessage(HttpMethod.Get, Url);
        return HttpClient.SendAsync(RequestMessage).Result.Content.ReadAsStringAsync().Result;
    }

Shorter version, which does not show the full "transformational" path of our http-request and uses GetStringAsync method of HttpClient object. Function just creates new instance of HttpClient class (an HttpClient object), uses GetStringAsync method to get response body(content) of our http request as an async-task result\promise, and then uses .Result property of that async-task-result to get final string and after that simply returns this string as a function return.

static string GetStringSync(string Url)
    {
        HttpClient HttpClient = new HttpClient();
        return HttpClient.GetStringAsync(Url).Result;
    }

Usage:

const string url1 = "https://microsoft.com";
const string url2 = "https://stackoverflow.com";

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; /*sets TLC protocol version explicitly to modern version, otherwise C# could not make http requests to some httpS sites, such as https://microsoft.com*/

Console.WriteLine(GetHttpContentAsString(url1)); /*gets microsoft main page html*/
Console.ReadLine(); /*makes some pause before second request. press enter to make second request*/
Console.WriteLine(GetStringSync(url2)); /*gets stackoverflow main page html*/
Console.ReadLine(); /*press enter to finish*/

Full code:

enter image description here

1 Comment

I suspect it'd be cleaner if you used return await x.ReadAsStringAsync(); instead of explicitly requesting the result. In this case, it does the same thing. However, in a sharp scenario, it may inflict on the performance. Also, await is best-practice recommended.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.