Reputation: 165
I want to deserialize a JSON stream to an JToken object (It could be JObject/JArray/JToken, but referred to as JToken). I want to use the result as an JToken object, not some other class instance like most examples show.
How can this be done?
Upvotes: 4
Views: 1706
Reputation: 116806
To load a Stream
as a JToken
, you can use either of the following:
JToken.Load(JsonReader, JsonLoadSettings)
JsonSerializer.Deserialize<JToken>(JsonReader, JsonSerializerSettings)
First create one or both of the following methods:
public static partial class JsonExtensions
{
public static JToken LoadFromStream(Stream s, JsonLoadSettings settings = default, bool closeInput = true, FloatParseHandling? floatParseHandling = default, DateParseHandling? dateParseHandling = default)
{
using (var reader = new StreamReader(s))
using (var jsonReader = new JsonTextReader(reader) { CloseInput = closeInput })
{
if (floatParseHandling != null)
jsonReader.FloatParseHandling = floatParseHandling.Value;
if (dateParseHandling != null)
jsonReader.DateParseHandling = dateParseHandling.Value;
// You might also need to configure DateTimeZoneHandling, DateFormatString and Culture to fully control loading of dates and times.
return JToken.Load(jsonReader, settings);
}
}
public static T Deserialize<T>(Stream s, JsonSerializerSettings settings = default, bool closeInput = true)
{
// This method taken from this answer https://stackoverflow.com/a/22689976/3744182
// By https://stackoverflow.com/users/740230/ygaradon
// To https://stackoverflow.com/questions/8157636/can-json-net-serialize-deserialize-to-from-a-stream
// And modified to pass in settings and control whether the input stream is closed
using (var reader = new StreamReader(s))
using (var jsonReader = new JsonTextReader(reader) { CloseInput = closeInput })
{
JsonSerializer ser = JsonSerializer.CreateDefault(settings);
return ser.Deserialize<T>(jsonReader);
}
}
}
Given those methods, you can do either:
var token = JsonExtensions.LoadFromStream(stream, new JsonLoadSettings { /* Add your preferred load settings here */});
Or
var token = JsonExtensions.Deserialize<JToken>(stream, new JsonSerializerSettings { /* Add your preferred serializer settings here */ });
Notes:
Loading with JsonLoadSettings
allows you to control whether line position information is loaded (which is stored as an annotation and can take significant memory), whether comments are loaded, and how to handle duplicated property names.
Float format and Date/time recognition settings could be controlled by setting the necessary properties directly on JsonTextReader
.
Deserializing with JsonSerializerSettings
allows control of several parsing options including whether and how to recognize date/time strings as DateTime
or DateTimeOffset
and whether to load floats as double
or decimal
.
Line position information is not loaded when using JsonSerializer.Deserialize<JToken>()
.
Demo fiddle here.
Upvotes: 5