Convert a Stream into json value c# - c#

I have below stream which I get from this line where req1 is of HttpResponseMessage type and responseMessage is of type Stream. How can I convert this Stream into a json Object. My end goal is to extract values from the specific keys in this json.
var responseMessage = await req1.Content.ReadAsStreamAsync();

Above answer has a class defined. I didnt want to define different class as my model is dynamic. I found this solution , which worked well and got me the desired result
var serializer = new JsonSerializer();
using (var sr = new StreamReader(responseMessage))
using (var jsonTextReader = new JsonTextReader(sr))
{
var jsObj= serializer.Deserialize(jsonTextReader);
}

try it
// read file into a string and deserialize JSON to a type
Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(#"c:\movie.json"));
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
}

Related

How to Save Large Json Data?

i have a large ObservableCollection that I want to get out as Json file.
I used the following code, But I get an error out of memory
string json = JsonConvert.SerializeObject(content, Formatting.Indented);
await File.WriteAllTextAsync("file.json");
How can I save this huge ObservableCollection in a json file?
Instead of serializing to a string, and then writing the string to a stream, stream it directly:
using var stream = File.Create("file.json");
JsonSerializer.Serialize(stream, content, new JsonSerializerOptions
{
WriteIdented = true
});
try to serialize directly to the file.This way Newtosoft https://www.newtonsoft.com/json/help/html/serializewithjsonserializertofile.htm recomends to do it
using (StreamWriter file = File.CreateText(#"c:\file.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, content);
}

JsonDocument Get JSON String

I need an example of getting a JSON string from a JsonDocument. I can get properties with RootElement.GetProperty("ItemName") and then call .GetString() but can't see a way to just get the root element as a JSON string?
Here an example:
JsonDocument jdoc = JsonDocument.Parse("{\"a\":123}");
using(var stream = new MemoryStream())
{
Utf8JsonWriter writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
jdoc.WriteTo(writer);
writer.Flush();
string json = Encoding.UTF8.GetString(stream.ToArray());
}
For an easier usage you could put it in an extension method like:
public static string ToJsonString(this JsonDocument jdoc)
{
using (var stream = new MemoryStream())
{
Utf8JsonWriter writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
jdoc.WriteTo(writer);
writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}
}
And use it like:
JsonDocument jdoc = JsonDocument.Parse("{\"a\":123}");
string json = jdoc.ToJsonString();
I have use RootElement to get a JsonElement and then call .ToString().
JsonDocument jdoc = JsonDocument.Parse("{\"a\":123}");
string json = jdoc.RootElement.ToString();
For the record there are 2 code snippets in official doco at How to serialize and deserialize (marshal and unmarshal) JSON in .NET
A. Use JsonDocument to write JSON
The following example shows how to write JSON from a JsonDocument:
(surprisingly long code snippet here)
The preceding code:
Reads a JSON file, loads the data into a JsonDocument, and writes formatted (pretty-printed) JSON to a file.
Uses JsonDocumentOptions to specify that comments in the input JSON are allowed but ignored.
When finished, calls Flush on the writer. An alternative is to let the writer autoflush when it's disposed.
B. Use Utf8JsonWriter
The following example shows how to use the Utf8JsonWriter class:
(...)
The snipped can be adjusted to use JsonDocument.Parse:
using var stream = new System.IO.MemoryStream();
using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
{
var jsonDocument = JsonDocument.Parse(content);
jsonDocument.WriteTo(writer);
}
var formatted = System.Text.Encoding.UTF8.GetString(stream.ToArray());

How to parse the output from the web service which gives out JSON as output format. And I am using REST

How do I parse the output i.e., responseText?
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
//read response
var responseText = streamReader.ReadToEnd();
return responseText;
}
And, I know that string is the return type which I have specified as mentioned below.
public string InvokeRequest(RESTInvokeClass objInvoke)
I think the complete output(some 100 lines) which is in the JSON format is completely displaying as a single string stopping me to parse the output.
My question is:
How to receive the output so that I can parse through it?
If you just want to serialize the reponse text to an object that you can traverse through, you can do something like:
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
var riClass = jsSerializer.DeserializeObject(responseText);
foreach(var item in riClass)
{
//Do something with this item
}

How to use JsonTextReader twice

I am given a stream of json data which contains a field named "type". This type field describes the type of object that needs to be created at runtime. It looks like I am unable to use the JsonTextReader twice and I cannot find away to reset the text reader to the beginning.
using (var streamReader = new StreamReader(stream, Encoding))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
JToken token = JObject.Load(jsonTextReader);
var type = (string) token.SelectToken("type");
var modelType = Type.GetType("Project." + type + ", Project");
// Fails here
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
I get this error message.
Unexpected token while deserializing object: EndObject.
You can create a JsonReader from the JToken.
JsonReader reader = token.CreateReader();
To reset your reader to the begginning, set the Position property of the underlying stream to 0.
streamReader.BaseStream.Position = 0;
Edit:
While this will reset your underlying stream, the jsonTextReader is forward-only by definition, which means its line number and position are readonly. For this to work you would have to reset the streamReader position, then feed it into a new JsonTextReader object.
So unfortunately Phil, there is no way to read the JsonTextReader twice since it is forward-only.
Reference:
http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm
"Represents a reader that provides fast, non-cached, forward-only access to serialized Json data."
I cover using the JsonTextReader in a memory-efficient format, avoiding the Large Object Heap, etc., in my blog, as per James Newton King's recommendations. You can leverage this and the supplied code to read your JSON multiple times without worrying about the underlying implementation of JsonTextReader.
Comments and feedback always welcome.
I did some more testing and found that the following works.
Set JsonTextReader.CloseInput = false
Destroy the JsonTextReader (by closing the using statement)
Set StreamReader.BaseStream.Position = 0
Create a new JsonTextReader
It would look something like this:
using (var streamReader = new StreamReader(stream, encoding))
{
Type modelType = null;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
jsonTextReader.CloseInput = false;
JToken token = JObject.Load(jsonTextReader);
string type = (string)token.SelectToken("type");
modelType = Type.GetType("Project." + type + ", Project");
}
streamReader.BaseStream.Position = 0;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
}

How to handle JSON in C#?

Is there an easy/elegant parser for dealing with JSON in C#? How about actually serializing/deserializing into C# objects?
JSON.Net is a pretty good library
var jss = new JavaScriptSerializer();
var data = jss.Deserialize<dynamic>(jsonString);
Don't forget to reference "System.Web.Extensions"
See
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
Basically you can use the 'data contract' model (that's often used for WCF XML serialization) for JSON as well. It's pretty quick and easy to use standalone for little tasks, I have found.
Also check out this sample:
http://msdn.microsoft.com/en-us/library/bb943471.aspx
There's the DataContractJsonSerializer class.
Deserialize:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MyObject));
Stream s = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json_string));
MyObject obj = ser.ReadObject(s) as MyObject;
Serialize:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MyObject));
Stream s = new MemoryStream();
MyObject obj = new MyObject { .. set properties .. };
ser.WriteObject(s, obj);
s.Seek( SeekOrigin.Begin );
var reader = new StreamReader(s);
string json_string = reader.ReadToEnd();
DataContractJsonSerializer for serializing to/from objects.
In Silverlight 3, there's System.Json (http://msdn.microsoft.com/en-us/library/system.json(VS.95).aspx), very handy.

Categories