What should `ReadAsAsync<string>` and `ReadAsStringAsync` be used for?

10,078

ReadAsStringAsync: This is a basic "get me the content as a string" method. It will work on anything you throw at it because it's just strings.

ReadAsAsync<T>: This is meant to be used to deserialise a JSON response into an object. The reason it fails is because the JSON in the return is not a valid JSON representation of a single string. For example, if you serialise a string:

var result = JsonConvert.SerializeObject("hello world");
Console.WriteLine(result);

Output is:

"hello world"

Note how it is surrounded by double quotes. If you try to deserialise any arbitrary JSON directly into a string that isn't in the format "....." it will throw the exception you see because it is expecting the JSON to start with a ".

Share:
10,078

Related videos on Youtube

James Wood
Author by

James Wood

Updated on September 15, 2022

Comments

  • James Wood
    James Wood over 1 year

    What should HttpContentExtensions.ReadAsAsync<string> and HttpContent.ReadAsStringAsync be used for?

    They would seem to do similiar things but work in curious ways. A couple of tests and their outputs are below. In some cases JsonReaderException are thrown, in some cases, the JSON is output but with additional escape characters.

    I've ended up using both functions across my code base, but was hoping to align on one if I could understand how they were supposed to work.

    //Create data and serialise to JSON
    var data = new
    {
        message = "hello world"
    };
    string dataAsJson = JsonConvert.SerializeObject(data);
    
    //Create request with data
    HttpConfiguration config = new HttpConfiguration();
    HttpRequestMessage request = new HttpRequestMessage();
    request.SetConfiguration(config);
    request.Method = HttpMethod.Post;
    request.Content = new StringContent(dataAsJson, Encoding.UTF8, "application/json");
    
    string requestContentT = request.Content.ReadAsAsync<string>().Result; // -> JsonReaderException: Error reading string.Unexpected token: StartObject.Path '', line 1, position 1.
    string requestContentS = request.Content.ReadAsStringAsync().Result; // -> "{\"message\":\"hello world\"}"
    
    //Create response from request with same data
    HttpResponseMessage responseFromRequest = request.CreateResponse(HttpStatusCode.OK, dataAsJson, "application/json");
    
    string responseFromRequestContentT = responseFromRequest.Content.ReadAsAsync<string>().Result; // -> "{\"message\":\"hello world\"}"
    string responseFromRequestContentS = responseFromRequest.Content.ReadAsStringAsync().Result; // -> "\"{\\\"message\\\":\\\"hello world\\\"}\""
    
    //Create a standalone new response
    HttpResponseMessage responseNew = new HttpResponseMessage();
    responseNew.Content = new StringContent(dataAsJson, Encoding.UTF8, "application/json");
    
    string responseNewContentT = responseNew.Content.ReadAsAsync<string>().Result; // -> JsonReaderException: Error reading string.Unexpected token: StartObject.Path '', line 1, position 1.
    string responseNewContentS = responseNew.Content.ReadAsStringAsync().Result; // -> "{\"message\":\"hello world\"}"
    
  • Camilo Terevinto
    Camilo Terevinto almost 6 years
    And ReadAsAsync<T> is probably just a wrapper around JsonConvert.DeserializeObject<T>(await ReadAsStringAsync())
  • DavidG
    DavidG almost 6 years
    @CamiloTerevinto Actually it's not. ReadAsAsync<T> is much cleverer than that because it doesn't first pull the string into memory and then create your object.
  • DavidG
    DavidG almost 6 years
    @CamiloTerevinto Funnily enough there was a great Twitter thread about just this started by David Fowler (and if you don't know who he is... shame on you haha) twitter.com/davidfowl/status/1010403287521095680
  • Camilo Terevinto
    Camilo Terevinto almost 6 years
    Shame on me for not using Twitter I guess (but I do know him). According to this it's a Stream that's used instead of a string... interesting read. Thanks!
  • DavidG
    DavidG almost 6 years
    @CamiloTerevinto I'm not much of a Twitterer, but Fowler and Damian Edwards are great to follow and very responsive to answering questions.
  • DavidG
    DavidG almost 6 years
    Oh, and the ASP.NET Community Standups that are live streamed (live.asp.net) are also really useful.