using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace DownloadImagesTool
{
///
/// Temp Dynamic Converter
///
public class DynamicJsonConverter : JsonConverter
{
public override dynamic Read(ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.True)
{
return true;
}
if (reader.TokenType == JsonTokenType.False)
{
return false;
}
if (reader.TokenType == JsonTokenType.Number)
{
if (reader.TryGetInt32(out int i))
{
return i;
}
if (reader.TryGetInt64(out long l))
{
return l;
}
if (reader.TryGetDecimal(out decimal d))
{
return d;
}
return reader.GetDouble();
}
if (reader.TokenType == JsonTokenType.String)
{
if (reader.TryGetDateTime(out DateTime datetime))
{
return datetime;
}
//if(reader.TryGetBytesFromBase64(out byte[] byteResult))
//{
// return byteResult;
//}
return reader.GetString();
}
if (reader.TokenType == JsonTokenType.StartObject)
{
using JsonDocument documentV = JsonDocument.ParseValue(ref reader);
return ReadObject(documentV.RootElement);
}
// Use JsonElement as fallback.
// Newtonsoft uses JArray or JObject.
JsonDocument document = JsonDocument.ParseValue(ref reader);
return document.RootElement.Clone();
}
private object ReadObject(JsonElement jsonElement)
{
IDictionary expandoObject = new ExpandoObject();
foreach (var obj in jsonElement.EnumerateObject())
{
var k = obj.Name;
var value = ReadValue(obj.Value);
expandoObject[k] = value;
}
return expandoObject;
}
private object ReadValue(JsonElement jsonElement)
{
object result = null;
switch (jsonElement.ValueKind)
{
case JsonValueKind.Object:
result = ReadObject(jsonElement);
break;
case JsonValueKind.Array:
result = ReadList(jsonElement);
break;
case JsonValueKind.String:
//TODO: Missing Datetime&Bytes Convert
if(jsonElement.TryGetDateTime(out DateTime dtResult))
{
result = dtResult;
break;
}
//if(jsonElement.TryGetBytesFromBase64(out byte[] byteResult))
//{
// result = byteResult;
// break;
//}
result = jsonElement.GetString();
break;
case JsonValueKind.Number:
//TODO: more num type
if (jsonElement.TryGetInt32(out int i))
{
result = i;
break;
}
if (jsonElement.TryGetInt64(out long l))
{
result = l;
break;
}
if (jsonElement.TryGetDecimal(out decimal d))
{
result = d;
break;
}
result = jsonElement.GetDouble();
break;
case JsonValueKind.True:
result = true;
break;
case JsonValueKind.False:
result = false;
break;
case JsonValueKind.Undefined:
case JsonValueKind.Null:
result = null;
break;
default:
throw new ArgumentOutOfRangeException();
}
return result;
}
private object ReadList(JsonElement jsonElement)
{
IList