What should `ReadAsAsync<string>` and `ReadAsStringAsync` be used for?
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 "
.
Related videos on Youtube
James Wood
Updated on September 15, 2022Comments
-
James Wood over 1 year
What should
HttpContentExtensions.ReadAsAsync<string>
andHttpContent.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 almost 6 yearsAnd
ReadAsAsync<T>
is probably just a wrapper aroundJsonConvert.DeserializeObject<T>(await ReadAsStringAsync())
-
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 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 almost 6 yearsShame 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 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 almost 6 yearsOh, and the ASP.NET Community Standups that are live streamed (live.asp.net) are also really useful.