Skip to content

Instantly share code, notes, and snippets.

@DamianSuess
Created September 7, 2020 21:38
Show Gist options
  • Save DamianSuess/6b12ff51d3a9cf982a4ef616f009c99d to your computer and use it in GitHub Desktop.
Save DamianSuess/6b12ff51d3a9cf982a4ef616f009c99d to your computer and use it in GitHub Desktop.
System.Text.Json - Converters because the current one can't
/* Copyright Xeno Innovations, Inc. 2020
* Date: 2020-8-30
* File: DictionaryJsonConverter.cs
* Description:
* Dictionary JSON Converter
*
* Reference:
* - https://github.com/dotnet/runtime/blob/master/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.DictionaryGuidConverter.cs
* - https://github.com/dotnet/runtime/issues/30524
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace SampleApp.Core.Converters
{
public class DictionaryJsonConverter<TKey, TValue>
: JsonConverter<Dictionary<TKey, TValue>>
{
private readonly Converter<string, TKey> _keyParser;
private readonly Converter<TKey, string> _keySerializer;
public DictionaryJsonConverter(Converter<string, TKey> keyParser, Converter<TKey, string> keySerializer)
{
_keyParser = keyParser;
_keySerializer = keySerializer;
}
public static Dictionary<TKey, TValue> Read(
ref Utf8JsonReader reader,
Converter<string, TKey> keyParser,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
return null;
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException("Dictionary must be JSON object.");
var result = new Dictionary<TKey, TValue>();
while (true)
{
if (!reader.Read())
throw new JsonException("Incomplete JSON object");
if (reader.TokenType == JsonTokenType.EndObject)
return result;
var key = keyParser(reader.GetString());
if (!reader.Read())
throw new JsonException("Incomplete JSON object");
var value = JsonSerializer.Deserialize<TValue>(ref reader, options);
result.Add(key, value);
}
}
public override Dictionary<TKey, TValue> Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
return Read(ref reader, _keyParser, options);
}
public override void Write(
Utf8JsonWriter writer,
Dictionary<TKey, TValue> value,
JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
writer.WriteStartObject();
foreach (var pair in value)
{
writer.WritePropertyName(_keySerializer(pair.Key));
JsonSerializer.Serialize(writer, pair.Value, options);
}
writer.WriteEndObject();
}
}
}
}
/* Copyright Xeno Innovations, Inc. 2020
* Date: 2020-8-30
* File: TimeSpanJsonConverter.cs
* Description:
* TimeStamp JSON Convert for System.Text.Json
*/
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace SampleApp.Core.Converters
{
public class TimeSpanJsonConverter : JsonConverter<TimeSpan>
{
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return TimeSpan.Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment