DEV Community

Javid Gahramanov
Javid Gahramanov

Posted on

4 1

Polymorphic Serialization in .NET

In many applications, we often work with data that looks different but shares some common features. For example, a system might have different types of records or transactions that have similar properties but also their own unique details. Handling this kind of data can be tricky when saving or loading it as JSON.

We already know polymorphism lets us treat different types of objects as a single base type. Polymorphic serialization in .NET 7 makes it easy to work with different types of data that share common properties. With JsonPolymorphic and JsonDerivedType in System.Text.Json, you can save and load objects with a base class while keeping the unique details of each type.

In this article, I will talk about how JSON polymorphic serialization works and how we applied it to manage patient records in a Cardiology Practice Management System.

Let's look at the code:

Base type for patient records

[JsonPolymorphic(TypeDiscriminatorPropertyName = "recordType")]
[JsonDerivedType(typeof(ECGRecord), typeDiscriminator: "ECG")]
[JsonDerivedType(typeof(EchoCardiogramRecord), typeDiscriminator: "EchoCardiogram")]
[JsonDerivedType(typeof(CardiacEventRecord), typeDiscriminator: "CardiacEvent")]
[JsonDerivedType(typeof(ConsultationRecord), typeDiscriminator: "Consultation")]
public abstract class PatientRecordBase;

Enter fullscreen mode Exit fullscreen mode

Other derived types
Each type of patient record inherits from PatientRecordBase and adds its own unique fields.

public class ECGRecord : PatientRecordBase
{
    public int HeartRate { get; set; }

    public RhytmType RhythmType { get; set; }
}

public class EchoCardiogramRecord : PatientRecordBase
{
    public double EjectionFraction { get; set; }

    public string Observations { get; set; }
    .....
}

public class CardiacEventRecord : PatientRecordBase
{
    public string EventDescription { get; set; }

    public string Trigger { get; set; }

    public string Outcome { get; set; }
    .....
}

public class ConsultationRecord : PatientRecordBase
{
    public string DoctorNotes { get; set; }

    //we use same approach for prescriptions as well.
    //Doctor may prescribe different things,right?
    // such as : pharmaceutical drugs,Lifestylechanges,advices,tests
    public List<PrescriptionBase> Prescriptions { get; set; }
   .....
}
Enter fullscreen mode Exit fullscreen mode

Patient Records API


public class PatientRecordCreateRequest
{
    public string PatientId { get; set; }

    public DateTimeOffset DateTime { get; set; }

    public RecordType RecordType { get; set; }

    public PatientRecordBase Record { get; set; }
}

[Route("api/{patients}")]
[Authorize]
public class PatientRecordsController(IPatientService service, IMapper mapper) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> CreateAsync([FromBody] PatientRecordCreateRequest request)
    {
        // PatientRecord structure is same as PatientRecordCreateRequest 
        var patient = await service.CreateAsync(mapper.Map<PatientRecord>(request));
        return Ok(patient);
    }
}
Enter fullscreen mode Exit fullscreen mode

Let's see in action

Request payload

{
  "patientId": "p-7415879",
  "dateTime": "2024-11-30T06:07:44.390Z",
  "records": [
  {
    "recordType": "ECG",
    "heartRate": 72,
    "rhythmType": "Sinus"
  },
  {
    "recordType": "EchoCardiogram",
    "ejectionFraction": 55.6,
    "observations": "Normal function"
  },
  {
    "recordType": "Consultation",
    "doctorNotes": "Tachycardia during workout... "
  }
 ]
}
Enter fullscreen mode Exit fullscreen mode

Image description

Thanks for reading!

Billboard image

Monitoring as code

With Checkly, you can use Playwright tests and Javascript to monitor end-to-end scenarios in your NextJS, Astro, Remix, or other application.

Get started now!

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay