diff --git a/src/YesSql.Core/Serialization/DefaultContentSerializer.cs b/src/YesSql.Core/Serialization/DefaultContentSerializer.cs index 580a0d51..3515a57e 100644 --- a/src/YesSql.Core/Serialization/DefaultContentSerializer.cs +++ b/src/YesSql.Core/Serialization/DefaultContentSerializer.cs @@ -13,6 +13,7 @@ public DefaultContentSerializer() _options = new(); _options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; _options.Converters.Add(UtcDateTimeJsonConverter.Instance); + _options.Converters.Add(DynamicJsonConverter.Instance); } public DefaultContentSerializer(JsonSerializerOptions options) diff --git a/src/YesSql.Core/Serialization/DynamicJsonConverter.cs b/src/YesSql.Core/Serialization/DynamicJsonConverter.cs new file mode 100644 index 00000000..e67285ec --- /dev/null +++ b/src/YesSql.Core/Serialization/DynamicJsonConverter.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace YesSql.Serialization +{ + public class DynamicJsonConverter : JsonConverter + { + public static readonly DynamicJsonConverter Instance = new(); + + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.Null: + return null; + case JsonTokenType.False: + return false; + case JsonTokenType.True: + return true; + case JsonTokenType.String: + return reader.GetString(); + case JsonTokenType.Number: + { + if (reader.TryGetInt32(out var i)) + return i; + if (reader.TryGetInt64(out var l)) + return l; + // BigInteger could be added here. + if (reader.TryGetDouble(out var d)) + return d; + + throw new JsonException("Cannot parse number"); + } + case JsonTokenType.StartArray: + { + var list = new List(); + while (reader.Read()) + { + switch (reader.TokenType) + { + default: + list.Add(Read(ref reader, typeof(object), options)); + break; + case JsonTokenType.EndArray: + return list; + } + } + throw new JsonException(); + } + case JsonTokenType.StartObject: + IDictionary dict = new ExpandoObject(); + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonTokenType.EndObject: + return dict; + case JsonTokenType.PropertyName: + var key = reader.GetString(); + reader.Read(); + dict[key] = Read(ref reader, typeof(object), options); + break; + default: + throw new JsonException(); + } + } + throw new JsonException(); + default: + throw new JsonException(string.Format("Unknown token {0}", reader.TokenType)); + } + } + + public override void Write( + Utf8JsonWriter writer, + object objectToWrite, + JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); + } +}