Co-Authored-By: ta264 <ta264@users.noreply.github.com>pull/17/head
parent
428c9c034c
commit
596ba2dcbc
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Serializer
|
||||||
|
{
|
||||||
|
public class PolymorphicWriteOnlyJsonConverter<T> : JsonConverter<T>
|
||||||
|
{
|
||||||
|
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<T>(ref reader, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
JsonSerializer.Serialize(writer, value, value.GetType(), options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Serializer
|
||||||
|
{
|
||||||
|
public class STJHttpUriConverter : JsonConverter<HttpUri>
|
||||||
|
{
|
||||||
|
public override HttpUri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return new HttpUri(reader.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, HttpUri value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value.FullUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Serializer
|
||||||
|
{
|
||||||
|
public class STJUtcConverter : JsonConverter<DateTime>
|
||||||
|
{
|
||||||
|
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return DateTime.Parse(reader.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Serializer
|
||||||
|
{
|
||||||
|
public class STJVersionConverter : JsonConverter<Version>
|
||||||
|
{
|
||||||
|
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Version v = new Version(reader.GetString());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Serializer
|
||||||
|
{
|
||||||
|
public static class STJson
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions SerializerSettings = GetSerializerSettings();
|
||||||
|
private static readonly JsonWriterOptions WriterOptions = new JsonWriterOptions
|
||||||
|
{
|
||||||
|
Indented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
public static JsonSerializerOptions GetSerializerSettings()
|
||||||
|
{
|
||||||
|
var serializerSettings = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
AllowTrailingCommas = true,
|
||||||
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
serializerSettings.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, true));
|
||||||
|
serializerSettings.Converters.Add(new STJVersionConverter());
|
||||||
|
serializerSettings.Converters.Add(new STJHttpUriConverter());
|
||||||
|
serializerSettings.Converters.Add(new STJTimeSpanConverter());
|
||||||
|
serializerSettings.Converters.Add(new STJUtcConverter());
|
||||||
|
|
||||||
|
return serializerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Deserialize<T>(string json)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<T>(json, SerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object Deserialize(string json, Type type)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize(json, type, SerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object Deserialize(Stream input, Type type)
|
||||||
|
{
|
||||||
|
return JsonSerializer.DeserializeAsync(input, type, SerializerSettings).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryDeserialize<T>(string json, out T result)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = Deserialize<T>(json);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
result = default(T);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToJson(object obj)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(obj, SerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Serialize<TModel>(TModel model, Stream outputStream, JsonSerializerOptions options = null)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
options = SerializerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to object to get all properties written out
|
||||||
|
// https://github.com/dotnet/corefx/issues/38650
|
||||||
|
using (var writer = new Utf8JsonWriter(outputStream, options: WriterOptions))
|
||||||
|
{
|
||||||
|
JsonSerializer.Serialize(writer, (object)model, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore
|
||||||
|
{
|
||||||
|
public class LazyLoadedConverterFactory : JsonConverterFactory
|
||||||
|
{
|
||||||
|
public override bool CanConvert(Type typeToConvert)
|
||||||
|
{
|
||||||
|
if (!typeToConvert.IsGenericType)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeToConvert.GetGenericTypeDefinition() == typeof(LazyLoaded<>);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
var childType = type.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
return (JsonConverter)Activator.CreateInstance(
|
||||||
|
typeof(LazyLoadedConverter<>).MakeGenericType(childType),
|
||||||
|
BindingFlags.Instance | BindingFlags.Public,
|
||||||
|
binder: null,
|
||||||
|
args: new object[] { options },
|
||||||
|
culture: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LazyLoadedConverter<TChild> : JsonConverter<LazyLoaded<TChild>>
|
||||||
|
{
|
||||||
|
private readonly JsonConverter<TChild> _childConverter;
|
||||||
|
private readonly Type _childType;
|
||||||
|
|
||||||
|
public LazyLoadedConverter(JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
// For performance, use the existing converter if available.
|
||||||
|
_childConverter = (JsonConverter<TChild>)options
|
||||||
|
.GetConverter(typeof(TChild));
|
||||||
|
|
||||||
|
// Cache the type.
|
||||||
|
_childType = typeof(TChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LazyLoaded<TChild> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
TChild value;
|
||||||
|
if (_childConverter != null)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
value = _childConverter.Read(ref reader, _childType, options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = JsonSerializer.Deserialize<TChild>(ref reader, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
return new LazyLoaded<TChild>(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, LazyLoaded<TChild> value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value.IsLoaded)
|
||||||
|
{
|
||||||
|
if (_childConverter != null)
|
||||||
|
{
|
||||||
|
_childConverter.Write(writer, value.Value, options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JsonSerializer.Serialize(writer, value.Value, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue