Developing NS MedTrackerAugust 28, 2008
What Is HealthVault?
There is a plethora of health applications today. It’s not uncommon for an individual to use three or four applications to manage her weight, prescriptions, doctor visits, etc. Unfortunately each application has its own proprietary way of storing the data. For example, when a user wants to make her weight data available to her doctor, she has to rely on print-outs and emails. Microsoft recently announced the HealthVault platform to address this issue by providing an on-line data store, allowing applications to store a user’s health data. It provides a common platform for both devices and applications to manage the health data using a set of web services. These services can be programmed using the HealthVault API.
The user is in the center of this model. It’s up to the user to grant/deny access to applications that integrate with HealthVault. After the user grants access to a requesting application, data can be read/written to the user’s HealthVault account by that particular application. This central model also allows information exchange between applications. For example, if the user has given HealthVault access authorization to both a weight management and patient management system, a doctor using the patient management system can observe the weight fluctuations of that user as the data becomes available. This enables applications to have access to more data on demand. One particular area where this can be tremendously useful is decision support systems, wherein more data translates into improved outcome.
Below is a list of some of the major advantages of using HealthVault as a health data exchange platform:
- Storage of data is handled by HealthVault. This means your application will not have to worry about the security, maintenance, backup, or regulatory constraints on the data. HealthVault will be in charge of storage and the maintenance of data. With these taken care of, your application can concentrate on providing more functionality and value to users.
- Not having a data migration barrier will make it much easier for users of existing applications to switch over to another application. It will be as easy as signing up for your application, and the user will have all of her health data in the new application within a couple of minutes.
- By integrating with HealthVault your application will have access to device data that previously might not have been available. An accurate and frequent data feed might enable your application to provide functionality that previously hasn’t been possible to deliver.
Who Is It For?
There are three consumers of HealthVault services:
- Application developers
- Device manufacturers
Web applications (regardless of their platforms) can use a set of web services to read and write data from HealthVault. There are two ways in which to communicate with the HealthVault:
- Utilizing raw XML requests/responses
- Using the provided HealthVault SDK for .NET
For applications that are built on a different platform or that use a non-.NET language, the HealthVault XML API can be utilizied. This API consists of a set of XML web services. Note that doing so will require you to parse the returned XML responses before using the data.
Type of Applications and Usage Scenarios
One thing to keep in mind is that there is no silver bullet when integrating with HealthVault. Depending on the type of the application, integration methods and subsequent design decisions will change. For example, a decision support system will have drastically different data availability requirements than a cycling distance logger application. This, in turn, will affect the architecture of the applications when integrating with HealthVault. Please keep in mind that the sample app that we build will follow only one of the possible integration approaches with HealthVault.
Devices also will be able to send data directly to the HealthVault. HealthVault provides a desktop client that is able to recognize the connected devices and upload the data to the cloud. Device manufacturers will have to utilize the HealthVault DDK to benefit from this service.
Anyone with a Live ID account can sign up for a free HealthVault account. Once an account has been created, the user will have access to a list of applications that integrate with the HealthVault. Some of these applications are free while others require a fee for use. After signing up for a service, a user can return to the HealthVault web site to manage the applications’ access, and can also see the data available in the HealthVault.
How Are All consumers of the HealthVault Platform Connected?
Let’s take a look at a scenario to explain the interaction between all consumers of the HealthVault platform. Jay is a 50-year-old diabetic patient. He routinely takes blood glucose measurements at home using a device and records the values by hand. His doctor, Mary, gets a copy of these measurements to monitor the changes in his blood glucose in order to regulate the dosage of the insulin shots he receives. Jay, then takes the prescription and gets the new dosage from his pharmacy. Due to the manual nature of this process, Mary can only see the fluctuations every two weeks, she has to keep a separate record of this data for internal tracking purposes. Jay is recording the values by hand each day.
In a HealthVault-powered ecosystem, Jay uses his blood glucose measurement device to take the measurements. After taking the measurement, he connects the device to his laptop. New data results are automatically synchronized with Jay’s HealthVault account.
Jay then authorizes Mary to retrieve his health information in HealthVault using the HealthVault web site. This enables Mary to regularly monitor Jay’s blood glucose measurement fluctuations every day as more data becomes available.
Mary then uses a web application that integrates with HealthVault and retrieves new information about all her patients every night. The application also helps her chart the measurements over a period of time and correlate this information with the prescribed dosages of insulin. She also has the ability to track the fluctuations in values and overlay information about different medications that Jay was receiving. Consequently, she has access to more information about Jay’s reactions to different medications.
Alternatively, this application can send a reminder to Jay for an earlier foot/eye examination (a common exam for diabetic patients) if Mary notices an abnormal change in the measurements. In this ecosystem, there is no delay in the delivery of information. The patient and the primary care physician (PCP) can share medical records much more efficiently and be proactive about possible changes in patient conditions.
Here is a screenshot from the HealthVault illustration prepared by XPLANE that shows the envisioned future of a HealthVault ecosystem.
What Will We Do in This Article?
We will create a web application using ASP.NET and HealthVault SDK that tracks a user’s medications. This application will enable the user to track the medications she is taking over time. We will add more functionality as we go along.
We will be using the following technologies:
- ASP.NET 3.5
- Microsoft HealthVault SDK
In this section, we will be developing the basic structure of Netsoft MedTracker and take a closer look at how HealthVault authentication works. Note that you can either follow the steps here or download the complete source code. You will also need to download the HealthVault SDK to complete this section.
Setting Up the Project
Before we start writing code, we need to configure our HealthVault-enabled application and do some infrastructure work. A HealthVault application essentially has two properties associated with it:
- An application ID assigned by HealthVault (more on this later).
- A certificate installed under IIS.
Both steps above can be configured using the HealthVault Application Manager tool that comes as part of the HealthVault SDK. For the purposes of the MedTracker application we will refer to the Netsoft USA Demos certificate and application ID. It is assumed that you will create an application ID and a certificate for your application. Shortly, we will go through the necessary steps to create a new certificate and register it with HealthVault. If you already have a certificate, you can skip to the next section.
Launch the HealthVault Application Manager and click on Create New Certificate button. You will be prompted to enter a name of your application. Pick a name that you would like and click the OK button.
Now that the certificate is created on your workstation, it needs to be uploaded to the HealthVault for processing. Using the HealthVault Application Manager, right click on the newly created application name and select "Upload Certificate."
You will be taken to the Application Configuration Center where you will be able to get the application ID associated with your application. Replace the web.config specified default application ID with this value.
We will then add some keys to the web.config in order to configure MedTracker to use the newly created certificate and point to the HealthVault service URLs. Please see the full content of the web.config file before moving forward for additional keys.
21 <add key="ApplicationId" value="Netsoft Application ID" />
22 <add key="ShellUrl" value="https://account.healthvault-ppe.com/" />
23 <add key="HealthServiceUrl" value="https://platform.healthvault-ppe.com/platform/" />
25 <!-- when we call the SignOut() method on HealthServicePage, it redirects us to the page below -->
26 <add key="NonProductionActionUrlRedirectOverride" value="Redirect.aspx"/>
28 <!-- The redirect page (specified above) uses these keys below to redirect to different
29 pages based on the response from the shell -->
30 <add key="WCPage_ActionHome" value="default.aspx"/>
31 <add key="WCPage_ActionAppAuthSuccess" value="default.aspx"/>
32 <add key="WCPage_ActionSignOut" value="SignedOut.aspx" />
Notice the -ppe suffix in the Shell and Health Service URLs. Using these keys, we will point our application to the development sandbox environment instead of production.
Now we need to add references to the Microsoft HealthVault SDK DLLs.
HealthVault SDK provides us with the following functionality:
- Ensuring that the user is logged into HealthVault.
- Abstracting the HealthVault connection process.
- Abstracting item type serialization/deserialization from XML to .NET classes.
Authentication with HealthVault
We will now add a second page to our application that will serve as the authenticated home page. We will name this file Medications.aspx. This page will utilize the HealthVault SDK and ensure that the current user is logged into HealthVault in order to view the page. To enable this functionality, we need to derive Medications.aspx from HealthServicePage, instead of System.UI.Page.
13 using Microsoft.Health.Web;
15 public partial class Medications : HealthServicePage
17 protected void Page_Load(object sender, EventArgs e)
Now we need to decide on what kind of authentication mechanism we want to use for MedTracker. In order for MedTracker to store/retrieve HealthVault information on behalf of a user, the user needs to give necessary permissions to the application. Application permissions are set through the HealthVault shell (a set of web pages hosted at healthvault.com).
An application can use two connection modes when connecting to HealthVault in order to access information for a user:
- Live mode
- Offline mode
In live mode, the user needs to be presently logged into HealthVault through the browser. The user receives a token from the HealthVault shell that has an expiration date set on it. After the token is expired or the user closes the browser, the process needs to be repeated.
A health dashboard application that aggregates health data from different sources and displays it on a web page per the user’s request would use the live access mode since the user is already present.
With offline mode, after the user sets necessary permissions for an application, connections can be made from the application to HealthVault on behalf of the user without requiring the user to be logged into HealthVault.
A weight monitoring application that periodically pushes information to HealthVault based on a nightly schedule would use the offline access mode.
For the purposes of the MedTracker demo, we will be using live mode.
How Does Authentication Work?
We derived the Medications page from HealthServicePage instead of the generic Page class. Pages that derive from HealthServicePage have the OnPreLoad event look into the URL to receive a token or read the authentication information from a cookie. If the user is not authenticated with HealthVault, a redirect will be issued to the browser leaving your site to go to the HealthVault shell, where authentication will occur. Once authentication is complete, the user will be redirected back to a page indicated in the web.config based on the action that has been taken in HealthVault (successful authentication, etc). For example after a user successfully logs into HealthVault, she gets redirected to the pre-defined “gateway page.” Pre-defined in the development environment means a web.config entry:
26 <add key="NonProductionActionUrlRedirectOverride" value="Redirect.aspx"/>
Pre-defined in the production environment is a hard-coded URL on the HealthVault side that you supply as part of your application’s registration process (see the Go-Live guide). The gateway page is responsible for redirecting the user to different pages within your web application based on the HealthVault action. For example, if the user logs into HealthVault successfully the Gateway page will be called with a specific query string. It is then the gateway page’s responsibility to redirect the user to the correct page. Here is a list of different action pages you will need:
You can find more information on the semantics of each action URL at the MSDN HealthVault Reference Page.
Fortunately, the HealthVault SDK already comes with a built in page that reads web.config values and redirects the user to the appropriate page based on the action. All you need to do is to use the HealthServiceActionPage or a page that derives from it. NS MedTracker uses a page called Redirect.aspx that acts as a gateway. It looks like the following:
13 using Microsoft.Health.Web;
15 public partial class Redirect : HealthServiceActionPage
Below is a diagram summarizing the major steps of the authentication process.
Click on the thumbnail for larger image.
Application Permission Set-up
You will notice that the first time you run the application and sign into HealthVault, you will be prompted to give access to the Netsoft USA Demos application. How does HealthVault know that authentication should be given to Netsoft USA Demos application? Before we go forward there are a couple of things to keep in mind:
- HealthVault has the public key of the certificate that our application is using.
- IIS has access to the private key of the certificate.
The web.config keys that we have previously set up come into play here. When the application tries to communicate with HealthVault, it creates a WebApplicationConnection, which in turn takes an application ID and identifies the application to HealthVault. After authentication is complete, HealthVault encrypts the data using the public key associated with the application ID. After the user comes back to the application, the SDK uses the certificate to decrypt the authentication token and the user is authenticated.
Download the source code associated with this section here. Keep in mind that each section in the article builds on the previous one.
In the previous section of this article we looked at how authentication works with HealthVault. We created a simple shell for NS MedTracker that requires authentication with HealthVault to get to the Medications page. In this section we will look at how data is stored in HealthVault and how we use the SDK to interact with HealthVault types. We will complete our Medication page and let the user manage her medications.
How Are Types Stored in HealthVault?
HealthVault is a series of web services that work with XML. Consequently, all data that is stored in HealthVault is in XML format. A record in HealthVault is called a “thing.” For the rest of the article, we will refer to records as “things.” HealthVault allows different formats to store a thing in HealthVault:
- Pre-built thing types: HealthVault already defines a set of thing types that include definitions for a variety of different scenarios such as Medications, Lab Results, Aerobic Exercise, Procedures, etc. You can use one of these types to store the data in HealthVault. This is the most straight-forward approach.
- Extensions to thing types: If there is more information that you would like to store than the basic HealthVault schema allows you to, you can use extensions to a type. For example, if you would like to store the barcode information for a prescription that is used to receive a certain medication, you can use the extension point in the schema to store this additional data as a string (most preferably in a structured format like a key/value pair that can be parsed later on).
- Registering Private Types: HealthVault also allows registering of a new XML schema as a type. This new type can store the data in any way you please. The downside is that this format will not be a standard format. Even if other applications receive data in this format they might not know how to process it correctly.
- CCR/CCD: Finally, HealthVault also implements CCR/CCD standards. If you currently store data in this standard or want to standardize your data you can use these formats. You can learn more about CCR and CCD.
For our purposes, we will go with the pre-built thing types. NS MedTracker will utilize the Medication thing type defined by HealthVault.
What Does the SDK Provide to Deal with HealthVault Types?
HealthVault SDK contains classes that represent almost all of the available types in HealthVault. These classes facilitate the interaction with data on the .NET platform. They provide properties to easily set/get data from HealthVault types. These classes also undertake the task of representing the .NET classes in XML and vice versa. This saves a tremendous amount of time and enables the developer to work with .NET classes that can be bound to UI elements and interacted with easily.
Storing Data in HealthVault
Using the HealthVault SDK we have access to thing types. Since all types are .NET classes, we can instantiate a new class and then populate its properties. After populating the class we can call the HealthVault SDK to insert the item that we create into HealthVault. Here is a snippet that populates and inserts a Medication record into HealthVault. Note that this method is not used in the MedTracker application.
86 Medication medication = new Medication();
87 medication.Name = GetMedicationNameFromUI();
88 medication.Instructions = GetMedicationInstructionsFromUI();
89 medication.DaysSupply = GetMedicationDaysSupplyFromUI();
A couple of things happen when PersonInfo.SelectedRecord.NewItem() method is invoked:
- The object is serialized into XML.
- A request is sent to HealthVault through web services.
- A record is inserted and a unique ID is assigned to it.
- XML containing this information is returned from the HealthVault.
- The XML is deserialized into the object. It now includes all the fields + ID assigned by HealthVault.
Retrieving Data from HealthVault
To retrieve data from HealthVault we rely on the HealthVault SDK. We previously derived our Medications.aspx page from HealthServicePage instead of Page. HealthServicePage provides us with an instance of PersonInfo that identifies the currently authenticated user.
A person can have one or more records. We can think of records like folders. Each record in turn holds many “things” in it. Here is a diagram illustrating the hierarchy:
Searcher objects are used when retrieving the data from HealthVault. A searcher object is populated and executed. Following is a simple method that creates a Searcher and retrieves a user’s medication from HealthVault.
52 private IList<Medication> LoadMedicationsFromHealthVault()
54 List<Medication> medications = new List<Medication>();
55 var searcher = PersonInfo.SelectedRecord.CreateSearcher(); // Create a new search object.
57 // A searcher can contain multiple filters on it. This allows getting multiple result-sets witn one query.
58 // Add a new filter to the searcher object to get ALL medications.
61 var healthVaultQueryResult = searcher.GetMatchingItems();
62 var medicationCollection = healthVaultQueryResult; // We specified only one filter, so we will get only 1 collection back.
63 return Enumerable.Cast<Medication>(medicationCollection).ToList();
In the example above, we specify the searcher object that we will use to execute our query. The searcher object that is created is in the context of the currently authenticated person and the Selected Record. This makes sure that the query that we execute on line 61, is in the scope of a single record.
We then add a single filter to our searcher object (please note that a searcher can have multiple filters, which in turn will produce multiple result sets). We call the following helper method to add a new filter to the searcher:
66 private void AddMedicationFilterToSearcher(Microsoft.Health.HealthRecordSearcher searcher)
68 HealthRecordFilter filter = new HealthRecordFilter();
69 filter.TypeIds.Add(Medication.TypeId); // We want medications only. No additional filters such as name/date.
Note that the filter object has many more properties such as CreatedApplication, CreatedDate (Range), and EffectiveDate (Range) that you can utilize to filter the records. In addition to these public properties, you can also query the internals of a record using XPath property. In order to do this, you will have to look at the XML representation of the record and craft your XPath queries accordingly.
We get the first resultset from the matching collection of collections that is returned from the searcher. Since we have one filter we know that we will get one resultset. It's as simple as that (more on this in the next section).
Now that we have the medications we will cache them and display them in a grid. For brevity those snippets will be skipped. You can download the source code and take a look at it.
In the previous section of this article, we explored how items are stored in HealthVault, item/account hierarchy, and finally we developed a simple application to store/retrieve Medications from HealthVault using the available SDK. In this section, we will look at more advanced concepts.
Storing User Settings for an Application in HealthVault
In addition to storing health records that belong to a user, HealthVault also supports applications to store application-related user settings in HealthVault. If you are developing a HealthVault integrated application that uses HealthVault as the only data persistence medium, this feature eliminates the need to have a local database to store user related settings/preferences for your application.
Let's take a look at an example. The MedTracker application that we have been developing does not support changing the alternating row colors on the Medications page. We can create an application setting to store the alternate color that each user will pick. We can then store this setting in HealthVault, eliminating the need to keep a local database for the purpose of storing settings.
48 var settingsWriter = XmlWriter.Create(stream);
51 settingsWriter.WriteElementString("background", BackgroundColor);
One thing to notice in this snippet is the first element. HealthVault requires the first element in an XML settings snippet to be app-settings. The above code creates an XML settings snippet that has the background information we want to store for the currently logged-in user.
After storing the settings in HealthVault, the application settings can be read at any time from HealthVault. To minimize the number of calls to Healthvault we store the settings in the session after the first retrieval. Subsequent calls to retrieve the settings are satisfied by using the data in the session instead of calling HealthVault. Keep in mind that the settings need to be extracted from the XML snippet. Here is a code snippet that retrieves the data from HealthVault and extracts the background information that the user previously stored.
This in turn extracts the followign information:
30 public static ApplicationSettings LoadFromXML(IXPathNavigable settings)
32 if (settings == null)
33 return ApplicationSettings.CreateDefaultApplicationSettings();
34 var navigator = settings.CreateNavigator();
35 var bgNode = navigator.SelectSingleNode("/app-settings/settings/background");
Relationships Between Records Stored in HealthVault
In the previous section we looked at how records are stored in HealthVault. Each type is stored separately and can be retrieved by issuing a query. However, there might be some cases where an application might want to link correlated records. HealthVault provides such a facility through the HealthRecordItemRelationship type. Each type, such as Medication, Blood Pressure, etc., has a RelatedItems property that can be queried in order to retrieve the IDs of related items. An application can then extract these IDs and perform the necessary retrieval if needed. Keep in mind that the relationships are rather soft links and are not enforced in HealthVault. These links should not be treated as the foreign key constraints that we all are used to from the relational database world.
Here is a code snippet that will check if the medication has been prescribed by a certain physician. If a related physician contact is found, it will then query HealthVault to get the contact information. Note that this is not the optimal way of doing this. It’s for illustration purposes only, and the current demo does not utilize this functionality.
153 private bool TryExtractPhysicianContactInformation(Medication medication, out string physicianContactInformation)
155 if (medication == null)
156 throw new ArgumentNullException("medication");
157 if (medication.CommonData.RelatedItems != null || medication.CommonData.RelatedItems.Count > 0)
159 var physicianRelationships = (from r in medication.CommonData.RelatedItems
160 where r.RelationshipType == "Physician"
161 select r).ToList();
162 if (physicianRelationships.Count == 0)
163 return false;
164 return GetPhysicianContactInformation(physicianRelationships.ItemKey.Id);
Each relationship contains two properties: the RelationshipType and the ItemKey of the related item. In the above example we query all the relationships based on the RelationshipType property. Extract all the physicians and return the contact information of the first physician in the related items list.
This could be an interesting way to keep correlations in HealthVault, for example Medications can be linked to certain vital sign measurements based on the fill date. This could end up in an object graph that can be traversed based on just one piece of information. In particular, health dashboards could utilize this feature to come up with interesting visual representations for related health records.
Returning Multiple Result Sets with One Query
In the previous section we explored how to query HealthVault to return medication records for a user. By that model, we would have to call HealthVault N times to retrieve N different item types such as Medications, Procedures, etc. Fortunately, HealthVault allows sending multiple filters on a searcher object. This in return translates into multiple resultsets. For example, the snippet below will return all the Medications and Procedures that belong to a user in one call:
86 var searcher = this.PersonInfo.SelectedRecord.CreateSearcher();
87 var medicationFilter = new HealthRecordFilter();
89 var procedureFilter = new HealthRecordFilter();
91 searcher.Filters.Add(medicationFilter); // 0 - Medications
92 searcher.Filters.Add(procedureFilter); // 1 - Procedures
94 var resultSets = searcher.GetMatchingItems(); // Contains both collections.
95 var medications = resultSets;
96 var procedures = resultSets;
Things to Consider
Although we have covered the basics of HealthVault interaction there are some major items to consider when integrating your application with HealthVault. I will list some of the major pain points in integration:
- Unit of Measure Conversions: With multiple suppliers of data into a central repository comes the question of unit standardization. Your application might need to do some conversions before it can process the data that comes from HealthVault.
- Data Mapping and Translation: Existing applications work with schemas that have evolved over time to accommodate the business’ needs. There might not be an option for changing the internal schemas to conform to HealthVault type schemas. Additional mapping and transformation might be needed when converting local application types to HealthVault types and vice versa.
- Querying data: HealthVault provides search filters to query data. Advanced filters, however, require some knowledge about the internal representation of the type in order to craft the required XPath queries. This can be a major pain point for some applications that need to perform complex queries.