MedTracker - Part 2

Developing NS MedTracker – part 2
ItemTypes and Data Exchange

by Burag Cetinkaya

In Part 1 of the series 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 article 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 MedTracker application.

86 Medication medication = new Medication();

87 medication.Name = GetMedicationNameFromUI();

88 medication.Instructions = GetMedicationInstructionsFromUI();

89 medication.DaysSupply = GetMedicationDaysSupplyFromUI();

90 this.PersonInfo.SelectedRecord.NewItem(medication);


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 1 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:

HealthVault thing record person 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()

53 {

54 List<Medication> medications = new List<Medication>();

55 var searcher = PersonInfo.SelectedRecord.CreateSearcher(); // Create a new search object.

56

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.

59 AddMedicationFilterToSearcher(searcher);

60

61 var healthVaultQueryResult = searcher.GetMatchingItems();

62 var medicationCollection = healthVaultQueryResult[0]; // We specified only one filter, so we will get only 1 collection back.

63 return Enumerable.Cast<Medication>(medicationCollection).ToList();

64 }


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)

67 {

68 HealthRecordFilter filter = new HealthRecordFilter();

69 filter.TypeIds.Add(Medication.TypeId); // We want medications only. No additional filters such as name/date.

70 searcher.Filters.Add(filter);

71 }


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 1 filter we know that we will get 1 resultset. Simple as that (more on this in Part 3).

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.

Continue on to part 3 of this series.