Reading & Development: 1-2 hours
Overview
This developer guide helps developers to verify whether a My Health Record exists for a patient using their Individual Healthcare Identifier (IHI).
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.
More Information
The My Health Record was previously known as the Personally Controlled Electronic Health Record (PCEHR). All references in your product should refer to the system as the My Health Record, however you will note that some code uses the previous name PCEHR, i.e. the web service DoesPCEHRExist.
Prerequisites
- If you have not already done so, you should follow our HI Service Developer Guides.
- Visual Studio (2010 – 2019)
The following screenshots show the demonstration application created in the previous HI Service Developer Guides with the new extended functionality to interact with the My Health Record system. This guide will continue using this demonstration in addition to all of 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 second 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).
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
Step 2.1. Continue using the same solution and project created in the previous HI Service Developer Guides. You can create a new project if desired.
Step 2.2. Copy the command below into Package Manager Console and hit enter to install.
Install-Package Nehta.VendorLibrary.MHR
Step 2.3. Add the System.ServiceModel .NET framework library using the Add Reference window if it is not already added.
Step 3: Prepare a form for My Health Record
In these steps, you 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, you 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.
Step 4: Prepare configuration and common code
Before we make a call to DoesPCEHRExist:
• You will setup client configuration in App.Config and
• You will setup the Agency’s common code inside the Helper classes which will be used throughout the Developer Guides.
Step 4.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>
More Information
Make sure the values are replaced correctly. In case of incorrect values, your software will not be authenticated.
Step 4.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
Step 5.1. Add a new form called Patient Appointment as in the 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, you add input and output fields for SOAP request, response and returning errors for testing purposes.
Step 5.2. Disable the My Health Record button by default using the Windows form button properties. You 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.
Step 6: Add code to call DoesPCEHRExist
In these steps, you will 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.
Step 6.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();
}
Step 6.2. As you are passing the IHI number through the Patient Appointment Form constructor, you need to modify the class PatientAppointmentForm.cs as below. You can call DoesPCEHRExist using this IHI number. To modify class constructor, right click on “Patient Appointment Form” and click view code.
public PatientAppointmentForm(string ihiNumber)
{
InitializeComponent();
}
Step 6.3. Add the following 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;
}
}
Step 6.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);
}
Step 6.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
Step 7.1. Run the application and use a valid IHI number to open the Patient Appointment screen.
If you use a valid IHI, 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. This information will be used in the next Developer Guide, Gain Access to a My Health Record.
Step 7.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.
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 Clinical Information System (CIS) Software Systems Conformance Testing. To provide some direction to you, you can view a description of 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 Name | Check if an advertised My Health Record system exists |
Purpose | To check whether a healthcare recipient currently has an advertised My Health Record system. |
Test Case ID | PCEHR_CIS_019100 |
---|---|
Objective | When accessing the My Health Record 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 My Health Record system) that is connected to the HI Service. The relevant HI Use Cases and software requirements are documented in the My Health Record system CIS Conformance Assessment Scheme. |
How to Evaluate | Software should evaluate and ensure the following criteria when accessing with My Health Record (My Health Record 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 (My Health Record system) if: "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 the HI Service Developer Guides.
More Information
If you haven’t already, view the HI Service Developer Guides to explore the HI Service.
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 ID | PCEHR_CIS_019378 |
---|---|
Objective | The Clinical Information System should have the capability to audit interactions with the My Health Record 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. 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
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 the Agency's guide on uploading clinical documents.
If you have any feedback about this guide, please contact us at [email protected].
View All | Back | Next: Gain access to a My Health Record - My Health Record B2B Developer Guide 2