Skip to content

Instantly share code, notes, and snippets.

@AThraen
Created March 7, 2023 14:59
Show Gist options
  • Select an option

  • Save AThraen/24c67fb3dd590df167aa5be940975596 to your computer and use it in GitHub Desktop.

Select an option

Save AThraen/24c67fb3dd590df167aa5be940975596 to your computer and use it in GitHub Desktop.
Useful JsonConverters for serializing with System.Text.Json.
public class CustomStringConversionJsonConverter<G> : JsonConverter<G>
{
private readonly Func<G, string> _convertToString;
private readonly Func<string, G> _convertFromString;
public CustomStringConversionJsonConverter(Func<G,string> ConvertToString, Func<string,G> ConvertFromString)
{
_convertFromString = ConvertFromString;
_convertToString = ConvertToString;
}
public override bool CanConvert(Type typeToConvert)
{
return typeof(G).IsAssignableFrom(typeToConvert);
}
public override G? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException();
}
var s = reader.GetString();
return _convertFromString(s);
}
public override void Write(Utf8JsonWriter writer, G value, JsonSerializerOptions options)
{
writer.WriteStringValue(_convertToString(value));
}
}
public class IgnoreTypeInJsonConverter<G> : JsonConverter<G> where G: class
{
public override bool CanConvert(Type typeToConvert)
{
return typeof(G) == typeToConvert;//.IsAssignableFrom(typeToConvert);
}
public override G? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) return default(G);
}
}
else reader.Read();
return default(G);
}
public override void Write(Utf8JsonWriter writer, G value, JsonSerializerOptions options)
{
//Do nothing
writer.WriteNullValue();
}
}
public class PolymorphicJsonConverter<G> : JsonConverter<G>
{
//Inspired by https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to?pivots=dotnet-6-0#support-polymorphic-deserialization
public override bool CanConvert(Type typeToConvert)
{
return typeof(G) == typeToConvert;//.IsAssignableFrom(typeToConvert);
}
public override G Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
reader.Read();
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
string? propertyName = reader.GetString();
if (propertyName != "_type")
{
throw new JsonException();
}
reader.Read();
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException();
}
string type = reader.GetString();
//Check type exists
var tp=Type.GetType(type);
reader.Read();
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
propertyName = reader.GetString();
if (propertyName != "_object")
{
throw new JsonException();
}
var rt= (G) JsonSerializer.Deserialize(ref reader, tp, options);
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) return rt;
}
return rt;
}
public static T Cast<T>(object o)
{
return (T)o;
}
public override void Write(Utf8JsonWriter writer, G value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("_type", value.GetType().AssemblyQualifiedName);
writer.WritePropertyName("_object");
JsonSerializer.Serialize(writer, value, value.GetType());
writer.WriteEndObject();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment