|
@@ -6,6 +6,7 @@ using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Text.Json;
|
|
|
using System.Text.Json.Serialization;
|
|
|
+using System.Text.Json.Serialization.Metadata;
|
|
|
using InABox.Clients;
|
|
|
|
|
|
namespace InABox.Core
|
|
@@ -43,15 +44,12 @@ namespace InABox.Core
|
|
|
return _converters;
|
|
|
}
|
|
|
|
|
|
- private static JsonSerializerOptions SerializerSettings(bool indented = true)
|
|
|
+ private static JsonSerializerOptions SerializerSettings(bool indented = true, bool populateObject = false)
|
|
|
{
|
|
|
- var serializerSettings = CreateSerializerSettings();
|
|
|
- serializerSettings.WriteIndented = indented;
|
|
|
-
|
|
|
- return serializerSettings;
|
|
|
+ return CreateSerializerSettings(indented, populateObject);
|
|
|
}
|
|
|
|
|
|
- public static JsonSerializerOptions CreateSerializerSettings(bool indented = true)
|
|
|
+ public static JsonSerializerOptions CreateSerializerSettings(bool indented = true, bool populateObject = false)
|
|
|
{
|
|
|
var settings = new JsonSerializerOptions { };
|
|
|
|
|
@@ -59,6 +57,10 @@ namespace InABox.Core
|
|
|
{
|
|
|
settings.Converters.Add(converter);
|
|
|
}
|
|
|
+ if (populateObject)
|
|
|
+ {
|
|
|
+ settings.TypeInfoResolver = new PopulateTypeInfoResolver(new DefaultJsonTypeInfoResolver());
|
|
|
+ }
|
|
|
|
|
|
settings.WriteIndented = indented;
|
|
|
return settings;
|
|
@@ -149,6 +151,40 @@ namespace InABox.Core
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ [return: MaybeNull]
|
|
|
+ public static void DeserializeInto<T>(string? json, T obj, bool strict = false)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(json))
|
|
|
+ return;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var settings = SerializerSettings(populateObject: true);
|
|
|
+ PopulateTypeInfoResolver.t_populateObject = obj;
|
|
|
+ if (typeof(T).IsArray)
|
|
|
+ {
|
|
|
+ JsonSerializer.Deserialize<T>(json, settings);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ JsonSerializer.Deserialize<T>(json, settings);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ if (strict)
|
|
|
+ {
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+
|
|
|
+ CoreUtils.LogException("", e);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ PopulateTypeInfoResolver.t_populateObject = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public static object? Deserialize(Type T, string json) // where T : new()
|
|
|
{
|
|
|
var ret = T.GetDefault();
|
|
@@ -210,6 +246,45 @@ namespace InABox.Core
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
+ internal class PopulateTypeInfoResolver : IJsonTypeInfoResolver
|
|
|
+ {
|
|
|
+ private readonly IJsonTypeInfoResolver? _jsonTypeInfoResolver;
|
|
|
+
|
|
|
+ [ThreadStatic]
|
|
|
+ internal static object? t_populateObject;
|
|
|
+
|
|
|
+ public PopulateTypeInfoResolver(IJsonTypeInfoResolver? jsonTypeInfoResolver)
|
|
|
+ {
|
|
|
+ _jsonTypeInfoResolver = jsonTypeInfoResolver;
|
|
|
+ }
|
|
|
+
|
|
|
+ public JsonTypeInfo? GetTypeInfo(Type type, JsonSerializerOptions options)
|
|
|
+ {
|
|
|
+ var typeInfo = _jsonTypeInfoResolver?.GetTypeInfo(type, options);
|
|
|
+ if(typeInfo != null && typeInfo.Kind != JsonTypeInfoKind.None)
|
|
|
+ {
|
|
|
+ var defaultCreateObject = typeInfo.CreateObject;
|
|
|
+ if(defaultCreateObject != null)
|
|
|
+ {
|
|
|
+ typeInfo.CreateObject = () =>
|
|
|
+ {
|
|
|
+ if (t_populateObject != null)
|
|
|
+ {
|
|
|
+ var result = t_populateObject;
|
|
|
+ t_populateObject = null;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return defaultCreateObject.Invoke();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return typeInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public class CoreBinaryReader : BinaryReader
|
|
|
{
|
|
|
public BinarySerializationSettings Settings { get; set; }
|