FHIR Programming using .NET - Working with Canadian FHIR Profiles

Introduction

Welcome back to our FHIR programming series using .NET. In this article, we will explore FHIR profiles and demonstrate their practical application using Canadian Core profiles. Profiles are one of FHIR's most powerful features, allowing organizations and jurisdictions to customize the base FHIR specification to meet their specific requirements while maintaining interoperability.

This tutorial builds upon our previous discussions, including our exploration of building SMART on FHIR applications. If you're unfamiliar with creating and validating resources, I recommend reviewing the earlier articles in this series before proceeding. By the end of this article, you'll understand what FHIR profiles are and how to create profile-compliant resources for Canadian healthcare systems.

What Are FHIR Profiles?

A FHIR profile is a set of constraints and extensions applied to a base FHIR resource. Think of the base FHIR specification as a flexible template that covers the broadest possible use cases. Profiles narrow down this template to meet specific needs while maintaining interoperability.

Profiles can:

  • Mark optional elements as required (cardinality constraints)
  • Restrict the allowed values for coded elements (value set bindings)
  • Add extensions for data elements not in the base specification
  • Remove elements that aren't needed for a particular use case
  • Provide additional documentation and guidance

Profiles are formally defined using StructureDefinition resources and are identified by a canonical URL. When a resource claims conformance to a profile, it includes that profile's URL in the meta.profile element.

Prerequisites

Before you begin, ensure you have the following:

  • An operational FHIR server or access to a public FHIR server.
  • The .NET SDK installed, available from the official .NET website.
  • Visual Studio installed, which you can download from the Visual Studio website.
  • You can find all the code demonstrated in this tutorial on GitHub here

“The aim of argument, or of discussion, should not be victory, but progress.” ~ Joseph Joubert

Canadian Core FHIR Profiles

Canada Health Infoway has developed the CA Core (Canadian Core) FHIR profiles to support healthcare interoperability across Canada. These profiles provide Canadian-specific constraints and extensions on base FHIR resources, ensuring consistency across provincial healthcare systems.

Key aspects of Canadian FHIR profiles include:

  • Provincial Health Numbers - Each province issues unique health identifiers with specific formats and naming systems
  • Canadian Postal Codes - Address validation following the A1A 1A1 format
  • Province/Territory Codes - Standard two-letter codes (ON, BC, QC, AB, SK, etc.)
  • Bilingual Support - Communication preferences for English and French
  • Professional Licensing - Provincial medical licensing identifiers

Understanding Profile Hierarchies and Implementation Guides

Before diving into the code, it's essential to understand how FHIR profiles are organized hierarchically and how implementation guides structure these profiles for specific use cases.

Profile Hierarchy

FHIR profiles form a hierarchy where each level adds more constraints:

Canadian FHIR Profile Hierarchy saravanansubramanian.com each level only adds constraints — deeper profiles automatically satisfy the parents Base FHIR Specification most flexible · fewest constraints http://hl7.org/fhir/StructureDefinition/ CA Core (Canadian Core) national-level Canadian constraints http://hl7.org/fhir/ca/core/ Provincial / Territorial Profiles e.g. Ontario · British Columbia · Quebec additional constraints for provincial systems Organization-Specific Profiles hospital systems · health authorities most constrained · specific to local needs

Each level in the hierarchy can only add constraints (tighten rules), never remove them. This ensures that a resource conforming to a more specific profile automatically conforms to its parent profiles.

Extensions in Canadian Profiles

Extensions allow profiles to add data elements not present in the base FHIR specification. Canadian profiles define several important extensions:

Standard Extensions (from the FHIR specification):

  • patient-birthPlace - Place of birth for the patient
  • patient-citizenship - Citizenship information
  • patient-religion - Religious affiliation

Canadian Extensions (defined by CA Core):

  • ext-patientbirthsex - Birth sex (distinct from administrative gender)
  • ext-indigenous-identity - Indigenous identity information
  • ext-ethnicity - Ethnic background

Custom Extensions (organization-defined):

  • Provincial-specific data requirements
  • Organization workflow elements
  • Integration-specific metadata
// Example: Adding a Canadian extension to a Patient
var patient = new Patient();

// Add the birth sex extension (CA Core defined)
patient.Extension.Add(new Extension
{
    Url = "http://hl7.org/fhir/ca/core/StructureDefinition/ext-patientbirthsex",
    Value = new CodeableConcept
    {
        Coding = new List<Coding>
        {
            new Coding
            {
                System = "http://hl7.org/fhir/administrative-gender",
                Code = "female",
                Display = "Female"
            }
        }
    }
});

Canadian Terminology Bindings

Canadian profiles bind coded elements to specific value sets that reflect Canadian healthcare terminology:

SNOMED CT Canadian Edition:

  • Canadian extension to SNOMED CT with Canada-specific concepts
  • Used for clinical findings, procedures, and diagnoses
  • Maintained by Canada Health Infoway

Canadian Clinical Drug Data Set (CCDD):

  • National drug terminology for Canadian medications
  • Includes Drug Identification Numbers (DINs)
  • Used for Medication and MedicationRequest resources

pan-Canadian LOINC Observation Code Database (pCLOCD):

  • Canadian subset of LOINC codes for laboratory observations
  • Ensures consistent lab result coding across provinces

Canada Health Infoway’s Role

Canada Health Infoway is the federally-funded organization that coordinates healthcare interoperability standards across Canada:

  • Profile Development - Creates and maintains CA Core profiles
  • Naming Systems - Publishes official identifier system URIs for all provinces
  • Terminology Services - Hosts Canadian terminology servers
  • Conformance Testing - Provides tools for validating Canadian FHIR implementations
  • Implementation Guidance - Publishes implementation guides and best practices

Implementation Guides Structure

The CA Core Implementation Guide follows a standard FHIR IG structure:

  • StructureDefinitions - Profile definitions constraining base resources
  • ValueSets - Collections of codes allowed for coded elements
  • CodeSystems - Canadian-specific code systems
  • NamingSystem - Definitions for identifier systems (health numbers, etc.)
  • SearchParameters - Custom search parameters for Canadian requirements
  • CapabilityStatement - Expected server capabilities for CA Core conformance
  • Examples - Sample resources demonstrating proper usage

Provincial Health Number Systems

Canada's healthcare system is provincially administered, meaning each province issues its own health identifiers. Here are the naming system URIs for major provinces:

ProvinceHealth Number NameNaming System URIFormat
OntarioOHIPca-on-patient-hcn10 digits
British ColumbiaPHNca-bc-patient-healthcare-id10 digits (starts with 9)
QuebecNAMca-qc-patient-healthcare-id4 letters + 8 digits
AlbertaPHNca-ab-patient-healthcare-id9 digits
SaskatchewanHSNca-sk-patient-healthcare-id9 digits

Step 1 of 5: Define Constants and Setup

First, let's set up the constants for Canadian profile URLs and identifier systems. This ensures consistency throughout your application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Hl7.Fhir.Serialization;

namespace Com.SaravananSubramanian.Fhir.CanadianProfiles
{
    class Program
    {
        // Canadian identifier system URLs (from Canada Health Infoway)
        private const string OntarioHealthNumberSystem =
            "https://fhir.infoway-inforoute.ca/NamingSystem/ca-on-patient-hcn";
        private const string BritishColumbiaPhnSystem =
            "https://fhir.infoway-inforoute.ca/NamingSystem/ca-bc-patient-healthcare-id";
        private const string AlbertaPhnSystem =
            "https://fhir.infoway-inforoute.ca/NamingSystem/ca-ab-patient-healthcare-id";
        private const string QuebecNamSystem =
            "https://fhir.infoway-inforoute.ca/NamingSystem/ca-qc-patient-healthcare-id";
        private const string SaskatchewanPhnSystem =
            "https://fhir.infoway-inforoute.ca/NamingSystem/ca-sk-patient-healthcare-id";

        // Canadian profile URLs
        private const string CaCorePatientProfile =
            "http://hl7.org/fhir/ca/core/StructureDefinition/profile-patient";
        private const string CaCorePractitionerProfile =
            "http://hl7.org/fhir/ca/core/StructureDefinition/profile-practitioner";
        private const string CaCoreOrganizationProfile =
            "http://hl7.org/fhir/ca/core/StructureDefinition/profile-organization";

These constants define the official naming systems published by Canada Health Infoway. Using the correct system URI is essential for interoperability, as it allows other systems to recognize and properly interpret the identifiers.

“In the middle of difficulty lies opportunity.” ~ Albert Einstein

Step 2 of 5: Create a CA Core Patient with Ontario Health Number

Now let's create a Patient resource that conforms to the CA Core Patient profile. The key elements include setting the profile in metadata, using the correct provincial health number system, and following Canadian address conventions.

private static Patient CreateOntarioPatient()
{
    var patient = new Patient
    {
        // Set CA Core Patient profile - this declares conformance to the profile
        Meta = new Meta
        {
            Profile = new List<string> { CaCorePatientProfile }
        },
        Identifier = new List<Identifier>
        {
            // Ontario Health Number (OHIP) - Format: 10 digits
            new Identifier
            {
                System = OntarioHealthNumberSystem,
                Value = "1234567890",
                Type = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0203",
                            Code = "JHN",
                            Display = "Jurisdictional health number"
                        }
                    }
                },
                Use = Identifier.IdentifierUse.Official,
                Period = new Period { Start = "2020-01-01" }
            },
            // Secondary identifier (Medical Record Number)
            new Identifier
            {
                System = "http://example.org/hospital/mrn",
                Value = "MRN-ON-12345",
                Type = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0203",
                            Code = "MR",
                            Display = "Medical record number"
                        }
                    }
                },
                Use = Identifier.IdentifierUse.Usual
            }
        },
        Name = new List<HumanName>
        {
            new HumanName
            {
                Use = HumanName.NameUse.Official,
                Family = "Tremblay",
                Given = new List<string> { "Marie", "Claire" },
                Prefix = new List<string> { "Ms." }
            }
        },
        Gender = AdministrativeGender.Female,
        BirthDate = "1985-03-15",
        Active = true,
        Address = new List<Address>
        {
            new Address
            {
                Use = Address.AddressUse.Home,
                Type = Address.AddressType.Physical,
                Line = new List<string> { "123 Yonge Street", "Unit 456" },
                City = "Toronto",
                State = "ON",  // Canadian province code
                PostalCode = "M5B 1M4",  // Canadian postal code format (A1A 1A1)
                Country = "CA"  // ISO 3166 country code
            }
        },
        Telecom = new List<ContactPoint>
        {
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Phone,
                Value = "+1-416-555-0123",
                Use = ContactPoint.ContactPointUse.Home
            },
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Email,
                Value = "[email protected]",
                Use = ContactPoint.ContactPointUse.Home
            }
        },
        Communication = new List<Patient.CommunicationComponent>
        {
            // English as preferred language
            new Patient.CommunicationComponent
            {
                Language = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "urn:ietf:bcp:47",
                            Code = "en-CA",
                            Display = "English (Canada)"
                        }
                    }
                },
                Preferred = true
            },
            // French as secondary language
            new Patient.CommunicationComponent
            {
                Language = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "urn:ietf:bcp:47",
                            Code = "fr-CA",
                            Display = "French (Canada)"
                        }
                    }
                }
            }
        }
    };

    return patient;
}

Notice how the profile URL is set in the Meta.Profile property. This declares that the resource conforms to the CA Core Patient profile. The identifier type code "JHN" (Jurisdictional health number) indicates this is a government-issued health identifier.

Step 3 of 5: Create Patients for Different Provinces

Each Canadian province has its own health number format and naming conventions. Let's create patients for Quebec and British Columbia to demonstrate the differences.

private static Patient CreateQuebecPatient()
{
    var patient = new Patient
    {
        Meta = new Meta
        {
            Profile = new List<string> { CaCorePatientProfile }
        },
        Identifier = new List<Identifier>
        {
            // Quebec NAM - Format: 4 letters + 8 digits (e.g., DUBO75010112)
            // The format encodes: first 4 letters of surname + birth date info
            new Identifier
            {
                System = QuebecNamSystem,
                Value = "DUBO75010112",
                Type = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0203",
                            Code = "JHN",
                            Display = "Jurisdictional health number"
                        }
                    }
                },
                Use = Identifier.IdentifierUse.Official
            }
        },
        Name = new List<HumanName>
        {
            new HumanName
            {
                Use = HumanName.NameUse.Official,
                Family = "Dubois",
                Given = new List<string> { "Jean-Pierre" },
                Prefix = new List<string> { "M." }  // French honorific
            }
        },
        Gender = AdministrativeGender.Male,
        BirthDate = "1975-01-01",
        Active = true,
        Address = new List<Address>
        {
            new Address
            {
                Use = Address.AddressUse.Home,
                Type = Address.AddressType.Physical,
                Line = new List<string> { "456 Rue Sainte-Catherine Ouest" },
                City = "Montreal",
                State = "QC",  // Quebec province code
                PostalCode = "H3B 1A2",
                Country = "CA"
            }
        },
        Telecom = new List<ContactPoint>
        {
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Phone,
                Value = "+1-514-555-0145",
                Use = ContactPoint.ContactPointUse.Home
            }
        },
        Communication = new List<Patient.CommunicationComponent>
        {
            // Quebec patient - French as preferred language
            new Patient.CommunicationComponent
            {
                Language = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "urn:ietf:bcp:47",
                            Code = "fr-CA",
                            Display = "French (Canada)"
                        }
                    }
                },
                Preferred = true
            }
        }
    };

    return patient;
}

private static Patient CreateBritishColumbiaPatient()
{
    var patient = new Patient
    {
        Meta = new Meta
        {
            Profile = new List<string> { CaCorePatientProfile }
        },
        Identifier = new List<Identifier>
        {
            // BC Personal Health Number (PHN) - Format: 10 digits starting with 9
            new Identifier
            {
                System = BritishColumbiaPhnSystem,
                Value = "9876543210",
                Type = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0203",
                            Code = "JHN",
                            Display = "Jurisdictional health number"
                        }
                    }
                },
                Use = Identifier.IdentifierUse.Official
            }
        },
        Name = new List<HumanName>
        {
            new HumanName
            {
                Use = HumanName.NameUse.Official,
                Family = "Wong",
                Given = new List<string> { "David", "Chen" }
            }
        },
        Gender = AdministrativeGender.Male,
        BirthDate = "1978-08-22",
        Active = true,
        Address = new List<Address>
        {
            new Address
            {
                Use = Address.AddressUse.Home,
                Type = Address.AddressType.Physical,
                Line = new List<string> { "789 Granville Street" },
                City = "Vancouver",
                State = "BC",  // British Columbia
                PostalCode = "V6Z 1K3",
                Country = "CA"
            }
        },
        Telecom = new List<ContactPoint>
        {
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Phone,
                Value = "+1-604-555-0199",
                Use = ContactPoint.ContactPointUse.Mobile
            }
        },
        Communication = new List<Patient.CommunicationComponent>
        {
            new Patient.CommunicationComponent
            {
                Language = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "urn:ietf:bcp:47",
                            Code = "en-CA",
                            Display = "English (Canada)"
                        }
                    }
                },
                Preferred = true
            },
            // BC has a significant Chinese-speaking population
            new Patient.CommunicationComponent
            {
                Language = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "urn:ietf:bcp:47",
                            Code = "zh-Hans",
                            Display = "Chinese (Simplified)"
                        }
                    }
                }
            }
        }
    };

    return patient;
}

Each province has unique characteristics reflected in the patient data. Quebec uses French names and addresses with "M." as a prefix instead of "Mr.", while British Columbia addresses the multicultural nature of its population with support for multiple languages.

“The secret of change is to focus all of your energy not on fighting the old, but on building the new.” ~ Socrates

Step 4 of 5: Create a CA Core Practitioner

Healthcare practitioners in Canada are licensed by provincial regulatory bodies. The CA Core Practitioner profile includes support for provincial licensing identifiers and professional qualifications.

private static Practitioner CreateCanadianPractitioner()
{
    var practitioner = new Practitioner
    {
        Meta = new Meta
        {
            Profile = new List<string> { CaCorePractitionerProfile }
        },
        Identifier = new List<Identifier>
        {
            // College of Physicians and Surgeons of Ontario (CPSO) license
            new Identifier
            {
                System = "https://fhir.infoway-inforoute.ca/NamingSystem/ca-on-license-physician",
                Value = "12345",
                Type = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0203",
                            Code = "MD",
                            Display = "Medical License Number"
                        }
                    }
                },
                Use = Identifier.IdentifierUse.Official,
                Period = new Period { Start = "2010-06-15" }
            }
        },
        Name = new List<HumanName>
        {
            new HumanName
            {
                Use = HumanName.NameUse.Official,
                Family = "Singh",
                Given = new List<string> { "Priya" },
                Prefix = new List<string> { "Dr." },
                Suffix = new List<string> { "MD, FRCPC" }
            }
        },
        Gender = AdministrativeGender.Female,
        Active = true,
        Address = new List<Address>
        {
            new Address
            {
                Use = Address.AddressUse.Work,
                Type = Address.AddressType.Physical,
                Line = new List<string> { "200 University Avenue" },
                City = "Toronto",
                State = "ON",
                PostalCode = "M5G 1V2",
                Country = "CA"
            }
        },
        Telecom = new List<ContactPoint>
        {
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Phone,
                Value = "+1-416-555-0200",
                Use = ContactPoint.ContactPointUse.Work
            },
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Email,
                Value = "[email protected]",
                Use = ContactPoint.ContactPointUse.Work
            }
        },
        Qualification = new List<Practitioner.QualificationComponent>
        {
            new Practitioner.QualificationComponent
            {
                Code = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://terminology.hl7.org/CodeSystem/v2-0360",
                            Code = "MD",
                            Display = "Doctor of Medicine"
                        }
                    }
                },
                Issuer = new ResourceReference { Display = "University of Toronto" },
                Period = new Period { Start = "2008-05-15" }
            },
            new Practitioner.QualificationComponent
            {
                Code = new CodeableConcept
                {
                    Coding = new List<Coding>
                    {
                        new Coding
                        {
                            System = "http://snomed.info/sct",
                            Code = "394802001",
                            Display = "General medicine"
                        }
                    }
                },
                Issuer = new ResourceReference
                {
                    Display = "Royal College of Physicians and Surgeons of Canada"
                },
                Period = new Period { Start = "2010-06-15" }
            }
        },
        Communication = new List<CodeableConcept>
        {
            new CodeableConcept
            {
                Coding = new List<Coding>
                {
                    new Coding
                    {
                        System = "urn:ietf:bcp:47",
                        Code = "en-CA",
                        Display = "English (Canada)"
                    }
                }
            },
            new CodeableConcept
            {
                Coding = new List<Coding>
                {
                    new Coding
                    {
                        System = "urn:ietf:bcp:47",
                        Code = "hi",
                        Display = "Hindi"
                    }
                }
            },
            new CodeableConcept
            {
                Coding = new List<Coding>
                {
                    new Coding
                    {
                        System = "urn:ietf:bcp:47",
                        Code = "pa",
                        Display = "Punjabi"
                    }
                }
            }
        }
    };

    return practitioner;
}

The practitioner example demonstrates several Canadian-specific elements: the CPSO (College of Physicians and Surgeons of Ontario) licensing system, the FRCPC credential from the Royal College of Physicians and Surgeons of Canada, and support for multiple languages reflecting Canada's multicultural population.

Step 5 of 5: Create a CA Core Organization and Submit Resources

Healthcare organizations in Canada also follow specific identification patterns. Let's create an organization and then submit our resources to a FHIR server.

private static Organization CreateCanadianOrganization()
{
    var organization = new Organization
    {
        Meta = new Meta
        {
            Profile = new List<string> { CaCoreOrganizationProfile }
        },
        Identifier = new List<Identifier>
        {
            new Identifier
            {
                System = "https://fhir.infoway-inforoute.ca/NamingSystem/ca-on-organization-id",
                Value = "12345678",
                Use = Identifier.IdentifierUse.Official
            }
        },
        Name = "Toronto General Hospital",
        Alias = new List<string> { "TGH", "University Health Network - Toronto General" },
        Type = new List<CodeableConcept>
        {
            new CodeableConcept
            {
                Coding = new List<Coding>
                {
                    new Coding
                    {
                        System = "http://terminology.hl7.org/CodeSystem/organization-type",
                        Code = "prov",
                        Display = "Healthcare Provider"
                    }
                }
            },
            new CodeableConcept
            {
                Coding = new List<Coding>
                {
                    new Coding
                    {
                        System = "http://terminology.hl7.org/CodeSystem/organization-type",
                        Code = "team",
                        Display = "Organizational Team"
                    }
                },
                Text = "Teaching Hospital"
            }
        },
        Active = true,
        Address = new List<Address>
        {
            new Address
            {
                Use = Address.AddressUse.Work,
                Type = Address.AddressType.Physical,
                Line = new List<string> { "200 Elizabeth Street" },
                City = "Toronto",
                State = "ON",
                PostalCode = "M5G 2C4",
                Country = "CA"
            }
        },
        Telecom = new List<ContactPoint>
        {
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Phone,
                Value = "+1-416-340-4800",
                Use = ContactPoint.ContactPointUse.Work
            },
            new ContactPoint
            {
                System = ContactPoint.ContactPointSystem.Url,
                Value = "https://www.uhn.ca/TorontoGeneral",
                Use = ContactPoint.ContactPointUse.Work
            }
        }
    };

    return organization;
}

static async System.Threading.Tasks.Task Main(string[] args)
{
    string fhirServerUrl = "http://hapi.fhir.org/baseR4";

    Console.WriteLine("FHIR .NET SDK - Canadian FHIR Profiles Tutorial");
    Console.WriteLine("===============================================");

    try
    {
        var settings = new FhirClientSettings
        {
            PreferredFormat = ResourceFormat.Json,
            ReturnPreference = ReturnPreference.Representation
        };

        var fhirClient = new FhirClient(fhirServerUrl, settings);

        // Create Canadian patients
        var ontarioPatient = CreateOntarioPatient();
        var quebecPatient = CreateQuebecPatient();
        var bcPatient = CreateBritishColumbiaPatient();

        // Create practitioner and organization
        var practitioner = CreateCanadianPractitioner();
        var organization = CreateCanadianOrganization();

        // Validate resources using serialization
        Console.WriteLine("\nValidating Canadian Resources...");
        var serializer = new FhirJsonSerializer(new SerializerSettings { Pretty = true });

        try
        {
            string json = serializer.SerializeToString(ontarioPatient);
            Console.WriteLine("Ontario Patient validation: PASSED");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Ontario Patient validation: FAILED - {ex.Message}");
        }

        // Submit resources to FHIR server
        Console.WriteLine("\nSubmitting resources to FHIR server...");

        var createdPatient = await fhirClient.CreateAsync(ontarioPatient);
        if (createdPatient != null)
        {
            Console.WriteLine($"Ontario Patient created with ID: {createdPatient.Id}");
            Console.WriteLine($"URL: {fhirServerUrl}/Patient/{createdPatient.Id}");
        }

        // Search for patients by provincial health number
        Console.WriteLine("\nSearching for patients with Ontario health numbers...");
        var searchParams = new SearchParams()
            .Where($"identifier={OntarioHealthNumberSystem}|");

        var searchResults = await fhirClient.SearchAsync<Patient>(searchParams);
        Console.WriteLine($"Found {searchResults?.Total ?? 0} patients.");
    }
    catch (FhirOperationException ex)
    {
        Console.WriteLine($"FHIR Operation Error: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error: {ex.Message}");
    }

    Console.WriteLine("\nTutorial completed.");
}

Canadian FHIR Profile Best Practices

When working with Canadian FHIR profiles, follow these best practices to ensure interoperability and compliance:

  • Always use the appropriate provincial health number system URI - Each province has its own naming system URL published by Infoway
  • Use Canadian postal code format (A1A 1A1) - Include the space between the two halves
  • Reference CA Core profile URLs in meta.profile - This declares your resource's conformance to the profile
  • Use standard Canadian province/territory codes - Use two-letter codes: ON, BC, QC, AB, SK, MB, NS, NB, PE, NL, NT, YT, NU
  • Include language preferences - Support for both English (en-CA) and French (fr-CA) is important for Canadian healthcare
  • Follow Infoway's pan-Canadian standards - Consult the official CA Core implementation guide for detailed requirements
  • Validate resources against CA Core profiles before production use - Use the validation techniques covered in earlier tutorials

Conclusion

In this article, we've explored FHIR profiles using Canadian Core profiles as practical examples. You've learned what profiles are and how they constrain base FHIR resources, how Canadian Core profiles support provincial health systems, how to create profile-compliant resources for patients, practitioners, and organizations, and best practices for working with Canadian FHIR implementations.

Profiles are essential for real-world FHIR implementations because they bridge the gap between FHIR's flexibility and the specific requirements of healthcare jurisdictions. By understanding how to work with profiles like CA Core, you're well-equipped to build interoperable healthcare applications that work within Canada's healthcare ecosystem.

The complete code for this tutorial is available on GitHub. For more information on Canadian FHIR profiles, visit the CA Core Implementation Guide.

This concludes the FHIR .NET programming series. Throughout this series, we've covered everything from setting up your environment, through CRUD operations, searching, validation, chaining operations, advanced topics including use of profiles in FHIR, security best practices, and finally building a SMART on FHIR application. You now have a comprehensive foundation for building robust, secure, and interoperable healthcare applications using FHIR and .NET. Thank you for following along!