Skip to content

Instantly share code, notes, and snippets.

@emonarafat
Created July 4, 2025 17:16
Show Gist options
  • Select an option

  • Save emonarafat/54357523f615f2b12e858f9005878fb9 to your computer and use it in GitHub Desktop.

Select an option

Save emonarafat/54357523f615f2b12e858f9005878fb9 to your computer and use it in GitHub Desktop.
System.Text.Json polymorphic converter for interface deserialization in .NET 6+
// PolymorphicJsonConverter.cs
using System.Text.Json;
using System.Text.Json.Serialization;
public interface INotification
{
string Type { get; }
}
public class EmailNotification : INotification
{
public string Type => "email";
public string Subject { get; set; }
public string EmailAddress { get; set; }
}
public class SmsNotification : INotification
{
public string Type => "sms";
public string PhoneNumber { get; set; }
public string Message { get; set; }
}
public class NotificationConverter : JsonConverter<INotification>
{
public override INotification Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
if (!doc.RootElement.TryGetProperty("type", out var typeProp))
throw new JsonException("Missing type discriminator");
return typeProp.GetString() switch
{
"email" => doc.RootElement.Deserialize<EmailNotification>(options),
"sms" => doc.RootElement.Deserialize<SmsNotification>(options),
_ => throw new JsonException($"Unknown notification type: {typeProp.GetString()}")
};
}
public override void Write(Utf8JsonWriter writer, INotification value, JsonSerializerOptions options)
{
switch (value)
{
case EmailNotification email:
JsonSerializer.Serialize(writer, email, options);
break;
case SmsNotification sms:
JsonSerializer.Serialize(writer, sms, options);
break;
default:
throw new NotSupportedException("Unknown type");
}
}
}
// Usage Example
var options = new JsonSerializerOptions
{
Converters = { new NotificationConverter() },
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string json = "{"type":"email","subject":"Hello","emailAddress":"[email protected]"}";
INotification note = JsonSerializer.Deserialize<INotification>(json, options);
// note is now an EmailNotification instance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment