Extending HealthVault data types using HealthRecordItemExtension

So, let's say that you're building an application using the HealthVault Height type, and you find that you need to store another bit of information with that type. What should you do?

Well, first, you should probably stop by HealthVault Forum and say, "I'm using Height, and I want to keep track of whether people were sleeping right beforehand, because spines compress during the day. How should I store that?"

The reason you should come by and ask is that the types that are currently in HealthVault are "works in progress" - they support the applications that are currently written but may need to be extended to support further applications. We'd therefore like to know what you're thinking to see whether your addition belongs in the base type. It might also be the case that that bit of extra information shouldn't be stored in the Height type but stored as an instance of some other type.

So, let's take it as read that you've already done that, and you want to extend an existing type. This is done through HealthRecordItem.CommonData.Extensions, which is a collection of HealthRecordItemExtension instances.

By default, there's nothing in this list. If you have an instance and you add an extension instance to it, the framework will dutifully save that instance out to the server, and just as dutifully fetch it back when you read that instance back out.

Assuming you do everything correctly.

There are two ways to do this. The first is a quick-and-somewhat-dirty method where you just stuff some xml into the extension and pull it out on the other side, and the second involves a nice object that encapsulates everything for you. This post will talk about the first method, and the next post will talk about the second method.

It's important to remember that this is a *list* of extensions, so you need to write your code so that it plays well with extensions that may have been put there by other users. That's fairly straightforward, but something to keep in mind...

Saving data to the vault 

Here's the code to add the extension data:

string extensionSourceName = "Fabrikam.UserSpineState";

HealthRecordItemExtension extension = new HealthRecordItemExtension(extensionSourceName);
height.CommonData.Extensions.Add(extension);

XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
navigator.InnerXml = @"<extension source=""" + extensionSourceName + @"""><SpineState>Compressed</SpineState></extension>";

The first line defines the source string. This is the "unique identifier" that differentiates your data from all the other data out there, so it's a good place to put a company name or some other unique string at the beginning.

We then create an instance of HealthRecordItemExtension with that name, and then finally add some xml to the extension. Note that the string in the extension source attribute has to be identical to the source you specified when you created the HealthRecordItemExtension instance.

That's all there is to it - when the height instance is saved, that data is persisted.

Pulling the data back out

To get the data out, we need to find our extension amongst the other extensions out there. So, assuming I have a Height instance, I can write the following:

foreach (HealthRecordItemExtension extension in height.CommonData.Extensions)
{
if (extension.Source == "Fabrikam.UserSpineState")
{
        XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
        XPathNavigator spineStateNavigator = navigator.SelectSingleNode("extension/SpineState");

        if (spineStateNavigator != null)
{
            string spineState = spineStateNavigator.Value;
}
}
}

And note that the source string I'm looking for is the same one I specified when I added the extension.

There are a few other properties that you can set on the extension:

Transform

If you'd like your extension data to be visible in applications that show data generically - such as the HealthVault.com data view - you can provide the url of an SSL transform that can convert the xml into html. 

Logo

Similarly, if you want a logo associated with the extension data, you can provide a url here.

Version

A version string that you can use for, surprise surprise, versioning.