Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient GetStreamAsync and HTTP status codes?

Tags:

I wish to use streams as recommended by the json.net performance tips documentation, however I'm unable to find how to get a hold of the http status codes without the typical awaiting the HttpResponse.

Is there perhaps a way of getting the status code first without reading the data? So still taking advantage of streams?

like image 351
Alex KeySmith Avatar asked May 11 '15 08:05

Alex KeySmith


People also ask

What is GetStreamAsync?

GetStreamAsync(String, CancellationToken) Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. GetStreamAsync(Uri) Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation.

What is Httpclient stream?

The stream represents an abstraction of a sequence of bytes in the form of files, input/output devices, or network traffic. The Stream class in C# is an abstract class that provides methods to transfer bytes – read from or write to the source.


2 Answers

I haven't tested to ensure it's performance, however this seems promising:

using(HttpClient client = new HttpClient())
{
    var response = await client.GetAsync("http://httpbin.org/get", HttpCompletionOption.ResponseHeadersRead);

    response.EnsureSuccessStatusCode();

    using (var stream = await response.Content.ReadAsStreamAsync())
    using (var streamReader = new StreamReader(stream))
    using (var jsonReader = new JsonTextReader(streamReader))
    {
      var serializer = new JsonSerializer();

       //do some deserializing http://www.newtonsoft.com/json/help/html/Performance.htm
    }
}
like image 55
Alex KeySmith Avatar answered Sep 19 '22 17:09

Alex KeySmith


I prefer to dispose of the HttpResponseMessage via using as it is disposable. I also prefer to not rely on exception handling to deal with failed requests. Instead I prefer to check against the IsSuccessStatusCode boolean value and proceed accordingly. For example:

using(HttpClient client = new HttpClient())
{
    using(var response = await client.GetAsync("http://httpbin.org/get", HttpCompletionOption.ResponseHeadersRead))
    {
        if(response.IsSuccessStatusCode)
        {
            using (var stream = await response.Content.ReadAsStreamAsync())
            using (var streamReader = new StreamReader(stream))
            using (var jsonReader = new JsonTextReader(streamReader))
            {
              var serializer = new JsonSerializer();

               //do some deserializing http://www.newtonsoft.com/json/help/html/Performance.htm
            }
        }
        else {
            //do your error logging and/or retry logic
        }
    }       
}

EDIT: If you're doing work with a rate limited api sending the HEAD request just isn't sometimes feasible. As such, here's a code sample using the good ol' fashion HttpWebRequest (note that there isn't a better way to deal with http errors than WebException in this case):

var req = WebRequest.CreateHttp("http://httpbin.org/get");

/*
 * execute
 */
try
{
    using (var resp = await req.GetResponseAsync())
    {
        using (var s = resp.GetResponseStream())
        using (var sr = new StreamReader(s))
        using (var j = new JsonTextReader(sr))
        {
            var serializer = new JsonSerializer();
            //do some deserializing http://www.newtonsoft.com/json/help/html/Performance.htm
        }
    }
}
catch (WebException ex)
{
    using (HttpWebResponse response = (HttpWebResponse)ex.Response)
    {
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            string respStr = sr.ReadToEnd();
            int statusCode = (int)response.StatusCode;

            //do your status code logic here
        }
    }
}
like image 33
pim Avatar answered Sep 19 '22 17:09

pim