DEV Community

Javid Gahramanov
Javid Gahramanov

Posted on

5 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!

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay