using System; using System.Collections.Generic; using System.Dynamic; using System.Globalization; using DPumpHydr.WinFrmUI.WenSkin.Json.Utilities; namespace DPumpHydr.WinFrmUI.WenSkin.Json.Converters { /// /// Converts an ExpandoObject to and from JSON. /// public class ExpandoObjectConverter : JsonConverter { /// /// Gets a value indicating whether this can write JSON. /// /// /// true if this can write JSON; otherwise, false. /// public override bool CanWrite => false; /// /// Writes the JSON representation of the object. /// /// The to write to. /// The value. /// The calling serializer. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { } /// /// Reads the JSON representation of the object. /// /// The to read from. /// Type of the object. /// The existing value of object being read. /// The calling serializer. /// The object value. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return ReadValue(reader); } private object ReadValue(JsonReader reader) { if (!reader.MoveToContent()) { throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); } switch (reader.TokenType) { case JsonToken.StartObject: return ReadObject(reader); case JsonToken.StartArray: return ReadList(reader); default: if (JsonTokenUtils.IsPrimitiveToken(reader.TokenType)) { return reader.Value; } throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } } private object ReadList(JsonReader reader) { IList list = new List(); while (reader.Read()) { switch (reader.TokenType) { case JsonToken.EndArray: return list; case JsonToken.Comment: continue; } object item = ReadValue(reader); list.Add(item); } throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); } private object ReadObject(JsonReader reader) { IDictionary dictionary = new ExpandoObject(); while (reader.Read()) { switch (reader.TokenType) { case JsonToken.PropertyName: { string key = reader.Value.ToString(); if (!reader.Read()) { throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); } object obj2 = (dictionary[key] = ReadValue(reader)); break; } case JsonToken.EndObject: return dictionary; } } throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. /// /// true if this instance can convert the specified object type; otherwise, false. /// public override bool CanConvert(Type objectType) { return objectType == typeof(ExpandoObject); } } }