Skip to main content
Guide
DG-3056
Status
Active
Version
1.0
Created
Updated

Reading & Development: 1-2 hours

Quick Intro

This developer guide helps you to verify whether a My Health Record exists for a patient using their Individual Healthcare Identifier (IHI). If you have not already done so, you should follow our HI Service Developer Guides.

In this example, you'll learn how to:

  • Setup the required libraries for My Health Record
  • Add the common code to be used throughout the My Health Record developer guides.
  • Extend the demonstration application previously created in the HI Service Developer Guides and add code to call the DoesPCEHRExist web service to check whether a My Health Record exists for a patient.

Verify your code and functionality against My Health Record Conformance use cases.

Prerequisites

  • Visual Studio (2010 – 2019)

The following screenshots show the demonstration application created in the previous HI Service Developer Guides with our new extended functionality to interact with the My Health Record system. We will continue using this demonstration throughout all of the My Health Record Developer Guides. At the end of this guide, you will have a patient appointment screen which verifies whether a My Health Record exists for a patient, and if so enables the My Health Record button. You will notice that the 2nd screenshot is a mockup of a very basic patient appointment screen, your software may have a similar screen (i.e. GP software) or may be based on entirely different workflows (i.e. Pharmacy Dispensing software).

mhr-guide1-1.png
CIS Main Form
mhr-guide1-2.png
Patient Appointment Screen

Introduction to DoesPCEHRExist

The DoesPCEHRExist web service takes an IHI as a parameter and returns true if the patient has a My Health Record and has not hidden it. The web services also indicates whether the patient has a Record Access Code (RAC) applied but does not indicate whether the patient has applied a Limited Document Access Code (LDAC). You will learn more about Access Codes in this guide and the next guide.

Once you have followed this guide you may wish to read further information about this web service. See our Logical & Technical Specifications here: My Health Record B2B Gateway Services v2.0 

Step 1: Download the sample code

This developer guide and upcoming guides use the sample code available at ADHA GitHub - MHR B2B Client .NET.
To see the full list of code samples and NuGet libraries, please go to the Open Source Sample Code Directory - GitHub and NuGet.

Step 2: Add the required libraries

1. We will continue using the same solution and project created in the previous HI Service Developer Guides. You can create a new project if desired.

2. Copy the command below into Package Manager Console and hit enter to install.

Install-Package Nehta.VendorLibrary.MHR

3.  Add the System.ServiceModel .NET framework library using the Add Reference window if it is not already added.

mhr-guide1-3.png
Visual Studio .NET Reference manager

Step 3: Prepare a form for My Health Record

In these steps, we will create a Patient Appointment button and text input field for the IHI. With the click of the Patient Appointment button, we will open the Patient Appointment screen and in the background check the DoesPCEHRExist web service. Calling DoesPCEHRExist will use the IHI number from the main screen. If the web service returns true, we will enable the My Health Record button to access the patient’s My Health Record Landing Page.

Add a panel for My Health Record with an IHI input field and button as shown in the screenshot Name the button and text field accordingly. In your software the Patient Appointment would likely be opened from a calendar or search and the IHI would be loaded from the patient’s records in your database.

mhr-guide1-4.png
CIS Main Form - My Health Record Tutorial

Step 4: Prepare configuration and common code

Before we make a call to DoesPCEHRExist, we will setup client configuration in App.Config and our common code inside the Helper classes which will be used throughout the Developer Guides.

1. Add the client configuration and other common settings inside the App.Config file or similar configuration method (if not present, please create one). Replace the values which are applicable to your organisation, some of which have been provided by Services Australia.

It is useful to note that the HI Service config values and the My Health Record config values are separate and will be different. If you are using an App.Config file or similar, be careful with naming your key value pairs.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>

	<appSettings>

		<!--Certification Seial No-->
		<add key="CertSerial" value="" />
		
		<!--Product Type Info-->
		<add key="Platform" value="" />
		<add key="ProductName" value=" " />
		<add key="ProductVersion" value="" />
		<add key="ProductVendor" value="" />

		<!-- Organization Info-->
		<add key="OrganisationName" value="" />
		<add key="OrganisationId" value="" />

              <!--My Health Record SVT EndPoints-->
		<add key="PCEHRExist" value="services.svt.gw.myhealthrecord.gov.au/doesPCEHRExist" />
		
	</appSettings>
</configuration>

2. Create a new class called PCEHRHelper inside the project and add the common static code to be used throughout the project.

a.  Import namespaces:

using System.Security.Cryptography.X509Certificates;
using Nehta.VendorLibrary.Common;
using Nehta.VendorLibrary.PCEHR;
using System.Configuration;

b. Replace the class with the following code. 

public static class PCEHRHelper
{

    private readonly static string Certificate_Serial = ConfigurationManager.AppSettings.Get("CertSerial");
    private readonly static string OrganizationName = ConfigurationManager.AppSettings.Get("OrganisationName");
    private readonly static string OrganizationId = ConfigurationManager.AppSettings.Get("OrganisationId");

    private readonly static string ProductPlatform = ConfigurationManager.AppSettings.Get("Platform");
    private readonly static string ProductName = ConfigurationManager.AppSettings.Get("ProductName");
    private readonly static string ProductVersion = ConfigurationManager.AppSettings.Get("ProductVersion");
    private readonly static string ProductVendor = ConfigurationManager.AppSettings.Get("ProductVendor");


    public static X509Certificate2 GetCertificate()
    {
        // NASH certificate should be used here, NOT the HI certificate. The NASH certificate can be found in the NASH PKI Test Kit
        // certificate needs to be installed in the right place
        // The "Issue To" field of a NASH certificate looks like general (or something different)."HPI-O".electronichealth.net.au
        // "Serial Number" can be found in the details once the certificate is installed.e.g. in Windows, certificates can be found in Certs.msc

        // Obtain the certificate for use with TLS and signing
        X509Certificate2 cert = X509CertificateUtil.GetCertificate(Certificate_Serial,X509FindType.FindBySerialNumber,
                StoreName.My,
                StoreLocation.CurrentUser,
                true);
        return cert;
    }

    public static CommonPcehrHeader CreateHeader()
    {
        // Create the PCEHR header
        var pcehrHeader = new CommonPcehrHeader();

        //User ID should be a HPI-I if the user is HPI-I eligible (i.e. AHPRA registered)
        // If the user isn't HPI-I eligible (such as support staff and scientific staff) then set the user ID to a local ID and
        // Set pcehrHeader.UserIdType to PCEHRHeaderUserIDType.LocalSystemIdentifier;
        pcehrHeader.UserId = "user ID";
        pcehrHeader.UserIdType = CommonPcehrHeaderUserIDType.PortalUserIdentifier;
        pcehrHeader.UserName = "user name";

        // "organisation name" and "organisation HPIO" can be found in the NASH PKI Test Kit
        // HPI-O is always 16 digits long
        pcehrHeader.OrganisationName = OrganizationName;
        pcehrHeader.OrganisationId = OrganizationId;

        pcehrHeader.ClientSystemType = CommonPcehrHeaderClientSystemType.CIS;

        // Below information can be found in the My Health Record Vendor Product Details Form
        // that you filled out and submitted
        pcehrHeader.ProductPlatform = ProductPlatform;
        pcehrHeader.ProductName = ProductName;
        pcehrHeader.ProductVersion = ProductVersion;
        pcehrHeader.ProductVendor = ProductVendor;

        return pcehrHeader;
    }
}

Step 5: Prepare a 'Patient Appointment' screen

1. Add a new form called Patient Appointment like screenshot shown below. This form is a very basic mockup of an appointment screen and you do not need to create the ListBoxes and other unused elements. Add the My Health Record button which your users will click to access the patient’s My Health Record landing page. The Finish Appointment (or a similarly titled button) will be important for future guides. On the bottom of form, we add input and output fields for SOAP request, response and returning errors for testing purposes.

2. Disable the My Health Record button by default using the Windows form button properties. We will enable the button if the patient with this given IHI exists in the My Health Record system. This will be covered in the next steps.

mhr-guide1-5.png
Create new form - Patient Appointment

Step 6: Add code to call DoesPCEHRExist

In these steps, we add the code to run DoesPCEHRExist in the background when the Patient Appointment screen is opened. If a My Health Record is found, the My Health Record button is enabled.

1. Double click on Patient Appointment button on the Main Form and add the following code. 

private void btnPatientAppointment_Click(object sender, EventArgs e)
{
    PatientAppointmentForm appointmentForm = new PatientAppointmentForm(txtIHINumber.Text);
    appointmentForm.Show();
}

2. As we are passing the IHI number through the Patient Appointment Form constructor, we need to modify the class PatientAppointmentForm.cs as below. We call DoesPCEHRExist using this IHI number. To modify class constructor, right on “Patient Appointment Form” and click view code. 

public PatientAppointmentForm(string ihiNumber)
{
    InitializeComponent();
}

3. Add the following the method inside Patient Appointment Form class. This method conducts the DoesPCEHRExist web service call, checks the response and enables the My Health Record button on the form.

private void DoesMyHealthRecordExist(string ihiNumber)
{
    // Obtain the certificate for use with TLS and signing
    X509Certificate2 cert = PCEHRHelper.GetCertificate();

    // Create PCEHR header
    CommonPcehrHeader header = PCEHRHelper.CreateHeader();
    // Override this value to the current patient's IHI.
    header.IhiNumber = ihiNumber;

    // Instantiate the client with Test environment endpoint.
    DoesPCEHRExistClient doesPcehrExistClient = new DoesPCEHRExistClient(
         new Uri(ConfigurationManager.AppSettings.Get("PCEHRExist")), cert, cert);

    // Add server certificate validation callback
    ServicePointManager.ServerCertificateValidationCallback += ValidateServiceCertificate;

    try
    {
        // Invoke the service
        doesPCEHRExistResponse response = doesPcehrExistClient.DoesPCEHRExist(header);

        if(response.PCEHRExists)
        {
            btnMyHealthRecord.Enabled = true;
        }

        // Get the soap request and response
        string soapRequest = doesPcehrExistClient.SoapMessages.SoapRequest;
        string soapResponse = doesPcehrExistClient.SoapMessages.SoapResponse;


        txtSOAPHeader.Text = soapRequest;
        txtSOAPResponse.Text = soapResponse;

    }
    catch (FaultException fex)
    {
        txtError.Text = fex.Message;
    }
    catch (Exception ex)
    {
        txtError.Text = ex.Message;
    }
}

4. To call this method, modify the Patient Appointment Form class constructor as below. As you would be aware a method such as this would be made asynchronously in your product.

public PatientAppointmentForm(string ihiNumber)
{
    InitializeComponent();
    DoesMyHealthRecordExist(ihiNumber);
}

5. Add the following additional namespaces and method in the patient appointment form class. 

using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using Nehta.VendorLibrary.Common;
using Nehta.VendorLibrary.PCEHR;
using Nehta.VendorLibrary.PCEHR.PCEHRProfile;
using System.Configuration;
private bool ValidateServiceCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    // Checks can be done here to validate the service certificate.
    // If the service certificate contains any problems or is invalid, return false. Otherwise, return true.
    // This example returns true to indicate that the service certificate is valid.
    return true;
}

Step 7: Test DoesPCEHRExist web service

1. Run the application and use a valid IHI number to open the Patient Appointment screen.
 

mhr-guide1-6.png
Does PCEHR Exist screen
mhr-guide1-7.png
Patient Appointment - My Health Record Exist Screen

If a valid IHI is used, it returns true for the PCEHRExists value in the SOAP response and the application code enables the My Health Record button on the Patient Appointment screen.

DoesPCEHRExist also returns the additional information accessCodeRequired which identifies whether record access is allowed or an Access Code is required. We will use this information in the next Developer Guide, Gain Access to a My Health Record. 

2. Now try using an invalid IHI and an IHI that does not have a My Health Record. The SOAP response returns false for the PCEHRExists value.

mhr-guide1-8.png
Patient Appointment - My Health Record Test screen

Step 8: My Health Record test cases

After running this sample code, it is important to review the Test Cases belonging to Use Case UC.CIS.001 which are part of CIS Software Systems Conformance Testing. To provide some direction to you, we will now describe several important test cases with code examples. You will need to meet the full list of test cases, please click here.

Use Case UC.CIS.001

Use Case NameCheck if an advertised PCEHR exists
PurposeTo check whether a healthcare recipient currently has an advertised PCEHR.
Test Case IDPCEHR_CIS_019100
Objective

When accessing the PCEHR System the Clinical Information System shall only use an individual healthcare identifier (IHI) if it has been validated or obtained during a configurable period, with the period determined by the local healthcare provider’s policy. This may be achieved by:

• Being connected to the HI Service; or

• Obtaining a valid IHI from another software system (other than the PCEHR System) that is connected to the HI Service.

The relevant HI Use Cases and software requirements are documented in the PCEHR CIS Conformance Assessment Scheme.

How to Evaluate

Software should evaluate and ensure the following criteria when accessing with My Health Record (PCEHER System)

1. CIS software prevents access when any of conditions matches:

Invalid IHI either validated or not validated within configurable period, has one or more unresolved alerts.

2. CIS software can access My Health Record (PCEHR System) if:

Valid IHI, has been validated or not validated within configurable period, and has no unresolved alerts.

"Validate" in this context means to send an IHI and demographic data to the HI Service for verification or to return an IHI for the provided demographic data for comparison with the CIS. 

The following code example demonstrates the use of the HI Service to validate an IHI before accessing the My Health Record system. Assume that your software has a method called ValidateIHI which validates as per the test case above. You will have created this functionality in our HI Service Developer Guides.

 

try
{

    // Verify the IHI for doesPcehrExist with My Health Record with HI Service 
    if (_hiService.ValidateIHI (txtIHINumber.Text))
    {
        // Invoke the service
        doesPCEHRExistResponse response = doesPcehrExistClient.DoesPCEHRExist(header);

        // Get the soap request and response
        string soapRequest = doesPcehrExistClient.SoapMessages.SoapRequest;
        string soapResponse = doesPcehrExistClient.SoapMessages.SoapResponse;

        txtSoapResponse.Text = soapResponse;
    }

}
catch (FaultException fex)
{

}
Test Case IDPCEHR_CIS_019378
ObjectiveThe Clinical Information System should have the capability to audit interactions with the PCEHR System.
How to Evaluate

Attempt to interact with My Health System, and verify:

a. It creates Audit logs when interacting with the system for any action performed.

Please note that this is a recommended requirement hence not mandatory.

This Code example demonstrates that each time a call is made to the My Health Record system, it creates a log entry using your local software’s logging system. Let’s consider the local software has a service called Logger, and a method which accepts some logging parameters such as action performed, software user, date time, IHI details, etc.

_logger.Log("Does PCEHR Exist", userId, ihiNumber, DateTime.Now);

Conclusion

If you have any feedback about this guide, please contact us at [email protected].

Now that you know whether a My Health Record exists and is advertised, In the next guide you will Gain Access to the patient’s My Health Record (if you are viewing) or you can progress to our guide on uploading clinical documents.

 

View All | Back | Next: Gain access to a My Health Record - My Health Record B2B Developer Guide 2