Search code examples
c#jsonserializationjson.net

How to deserialize a JSON stream to a JToken?


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?


Solution

  • To load a Stream as a JToken, you can use either of the following:

    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:

    Demo fiddle here.