Created
July 4, 2025 17:16
-
-
Save emonarafat/54357523f615f2b12e858f9005878fb9 to your computer and use it in GitHub Desktop.
System.Text.Json polymorphic converter for interface deserialization in .NET 6+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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