• Eric Gunnerson's Compendium

    Rekeying the HealthVault/Amalga USB Key


    If you attended the connected health conference last week, you got a USB key with a combination lock on it, so you could protect your important data against those with less than 10 minutes of free time, or those with very little imagination.

    But to get this protection, you'll need to change the combination to some other number. Here's how you do it:

    1. Set the key to 0-0-0
    2. On the non-usb end, there's a small round button. Press it in with a pen.
    3. Change the combination
    4. Press the button on the USB end back in.



  • Eric Gunnerson's Compendium

    Suggest a HealthVault topic...


    Is there something about HealthVault that you find confusing? If so, add a comment to this post, and I'll try to cover it in a future blog post.

  • Eric Gunnerson's Compendium

    7 Hills of Kirkland 2009

    7 Hills of Kirkland 2009
  • Eric Gunnerson's Compendium

    21st Century Breakdown


    I picked up a copy of Green Day's newest this morning at Fred Meyer, paying a princely $12.99 for the priviledge to do so. I missed picking it up last Saturday because of being busy and all, so I missed 3 days of listening.

    I've listened through a couple of times now. Musically, it's pretty wide-ranging - there are songs that are traditional Green Day, one song that sounds like it's directly from Money Money 2020 (a nice album if you like punk/new wave fusion), and one that's a little bit country (and more than a little bit rock and rock).

    They manage to sound both very much like Green Day and not like Green Day at the same time, if that makes any sense. I think it's a nice album, perhaps not as strong as American Idiot, but we'll see how it holds up to repeated listening

     And yes, I'll be at Key arena with the wife and (now old enough for a Green Day concert) daughter on July 3rd.



  • Eric Gunnerson's Compendium

    Microsoft Connected Health Conference


    The HealthVault Partner Conference is a year older and has a new name.

    The Microsoft Connected Health Conference will be held on June 10-12th at Meydenbauer Center in Bellevue, WA.

    If you enter the registration code on the page and choose "submit", you will get access to the details of the conference.

  • Eric Gunnerson's Compendium

    Progressio per Patientia


    "Progress through suffering"

    I have a friend (perhaps "riding acquaintance" is a more accurate term) named "Elden Fat Cyclist". Actually, that's his stage name. His real name is "Harold Fat Cyclist".

    Harold has been involved in Livestrong for a while and - for reasons that will become obvious if you read his blog - this year has decided to organize "Team Fat Cyclist", to try to win the team competition of the Livestrong challenge.

    This year, Livestrong has decided to hold a ride in Seattle. Their goal is apparently to do a shortened version of a Tour de France mountain stage, with an advertised 7900' of elevation gain over the 101 miles. That would, AFAIK, set a new standard for centuries in these parts, with the ever-popular (many would say "over-popular") Flying Wheels Century clocking in at 3500', and even the difficult 7 Hills century at only 7000'.

    Or, to put it another way, this ride will involve a significant amount of pain and suffering. Since signing up for rides that are harder than I should is a bit of a tradition for me (not to mention being a tradition for Harold), I signed up last week.

    That's where you come in.

    The event is a fundraiser for cancer research, and I'm looking for people to sponsor me in this undertaking.

    For the first $250 that's donated, I will match every dollar, and then Microsoft will match my dollar. So, if you donate $10, the total will be... well, it will be more than I can calculate on Sunny Seattle Spring Sunday.

    If you can spare some money to help out a worthy cause (cancer research, not me suffering), please head on over to my fundraising page.

  • Eric Gunnerson's Compendium

    Introduction to HealthvaultDevelopment #11: Data filtering


    The users are unhappy. The weight tracking application worked pretty well initially, but now that they’ve been using it daily for a few months, it’s showing them too much information. They would like it to show the recent results.

    That will take us into filtering…

    Filtering is done using the aptly-named HealthRecordFilter class. Thus far, we have only been using this class to filter to data that has the weight type id. In this episode we will explore additional ways to perform filtering.

    Common Data Filtering

    There are some properties that are shared across all data types. This section discusses filtering on those items.

    Filtering based on the number of items

    The simplest thing we can do is to only fetch a specific number of items rather than all of them. First, we add the following checkbox before the c_tableWeight table in default.aspx:

    <asp:CheckBox ID="c_CheckboxLast5Items" runat="server" Text="Last 5 items only" AutoPostBack="True" /><br />

    and then we change the filter definition in default.aspx.cs to:

    filter.View.Sections |= HealthRecordItemSections.Audits;
    if (c_CheckboxLast5Items.Checked)
        filter.MaxItemsReturned = 5;

    If you run this, when you click the checkbox you will only see the last 5 weight measurements.


    The HealthRecordItemCollection class implements lazy fetching of results. It will fetch chunks of instances at a time, going back to the server when it needs another chunk. The chunk size is set by the MaxFullItemsReturnedPerRequest property of the filter, and is 30 by default.

    This is transparent to the calling application, and the default value is usually fine.  Decreasing the value reduces the amount of work that the server has to do when processing each chunk, and might be required if your application deals objects that have significant amounts of data in them. This requires more trips to the server to fetch data, however, which will have performance implications.

    Increasing the value reduces the number of trips to the server to fetch all the data, but there is a possibility that the longer operations may result in a timeout.


    Filtering based on dates

    We can also filter based on the 

    First, add a checkbox above the table that allows the user to toggle this setting. You can do that through the designer or by adding the following before the c_tableWeight table:

    <asp:CheckBox ID="c_CheckboxLast3MonthsOnly" runat="server" Text="Last 3 months only" AutoPostBack="True" /><br />

    and the following is added to the filter definition:

    if (c_CheckboxLast3MonthsOnly.Checked)
        filter.UpdatedDateMin = DateTime.Now - new TimeSpan(30, 0, 0, 0);

    Filtering based on application id

    In a previous episode, we added some code to fetch the name of the application that last updated the data in HealthVault. We can filter on the application that last updated this data item so we only retrieve that items that our application retrieved (in general, apps should try to read all the data a user has, but it may make sense to only read this subset at times).

    This is done with the following:

    filter.UpdatedApplication = ApplicationConnection.ApplicationId;

    Adding the checkbox and the appropriate logic is left as an exercise to the reader.

    Type-Specific Filtering

    Filtering on a value that is specific to a type – the value of a weight measurement, the name of a medication is a bit more complex. The type-specific data for an instance is stored in HealthVault XML, so a filter needs to be able to find a specific piece of data inside of a larger chunk of XML and then compare it to a desired value.

    This is done using a query language that is known as XPath. To write an xpath expression for a specific HealthVault data type requires that you understand that XML format that is uses to store the information, which either requires getting the XML for a specific instance (by calling GetItemXml() on the instance), or understanding the XSD schema for the data type.

    To make this easier, I wrote the HealthVault XPath Explorer. This utility will let you easily walk the XML for instances that are in a specific HealthVault record, though you will have to figure out how to write the condition yourself. There are a number of good XPath tutorial available on the net.

    For our application, if we want to only return items where the weight value is less than 50 kilograms, we can use the following:

    filter.XPath = "/thing/data-xml/weight/value/kg[.> 50]";

    In the “[. > 50]”, the “.” refers to the current node, so it means “kg > 50”.

    Automatic user sign in

    You may have noticed that our demo app requires us to sign in every time we run it. This behavior is configurable:

    1. Go to the application configuration center
    2. Select the demo application
    3. Go to the “Misc” tab
    4. Toggle the “automatic user sign-in” radio button to “yes”
    5. Set a sign-in duration in seconds (I chose 3600).
    6. Click “Make changes”.

    That will start the configuration change process. Within 30 minutes, the update will make it to the servers, and a new “stay signed in” checkbox will appear on the log in page for the application.

    Next Time

    Next time we'll modify our application to work for the whole family.

  • Eric Gunnerson's Compendium

    HealthVault XPath Explorer


    By default, when a query is made to HealthVault, it returns all instances of a specific type. If you wish to filter to a subset of those instances, you can specify some properties in the HealthRecordFilter class. For example, you can set the CreatedApplication property to filter on the application that created the health record item.

    The filter properties, however, only works for properties that are shared across all data types. If you want to filter based on properties that are data-type-specific, you can do that by setting the XPath property to an appropriate XPath query.

    Creating that query is a bit inconvenient – perhaps a lot inconvenient – so I wrote a little utility that you can use to easily create an xpath query.

    You can find the code here.

    Make a copy of the HelloWorld sample, put the two files into it, and run the sample.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #10: Adding additional data to healthvault


    We have a new user request. One of our users would like to store how hungry he whenever he enters a weight value.

    We head off to the HealthVault MSDN page, go to the learn page and then the reference page, and then choose HealthRecordItem Type Schema Browser. This page talks to the developer platform to find out what types are currently supported by the platform.

    Looking through all the data types available on the page, we don’t find one related to hunger. So, we can just head home for the day and spend some quality time with our XBox.

    Or, we could explore other ways to add the hunger data to HealthVault.

    The first way is to ask the HealthVault team to add a new data type. We regularly add new data types and revise existing ones to meet the needs of our partners. If you think that the data you want to store is of general interest, please start a conversation with us.

    The downside of this is that it’s going to take us a while to figure out what the data type should be, design it, and then add it to a release. At best, it’s about 6 weeks from when we start working on it to when it shows up on your doorstep, gift-wrapped in a small box with a big red bow (gift wrap, box, and bow not included). If the type is complex, requires a lot of research, or if we’re especially busy, it could take longer.

    While you wait for us – or if the information is not of general interest – there are three ways to add information:

    • All data types provide the CommonData.Note and CommonData.Tags properties for your use.
    • All data types support adding extension data in XML format.
    • A custom application-specific data type can be created.

    Application-specific data types are only accessible by the application that created them, and there is therefore no data liquidity using such types. While there are scenarios where that makes sense, our guideline is that applications should make as much data as possible accessible to other applications, and therefore limit the use of application-specific types.


    Extensions are created and accessed using the HealthRecordItemExtension class, and there is a collection of these classes on the CommonData property of the data type instance.

    The XML for the extension is in the following format:

            xml data goes here

    The meaning of the XML data inside is purely up to the application.

    For hunger, we’ll use an entry like this:


    Adding the extension to our project

    In default.aspx, make the c_lableHunger and c_dropDownListHunger controls visible. Here’s the code we need to parse the values, create the extension, and add it to the weight object:

    void AddHungerToWeight(Weight weight)
        HealthRecordItemExtension extension = new HealthRecordItemExtension(ExtensionWeightTrackerHunger);
        XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
        string innerXml = @"<extension><hunger>" + c_dropDownListHunger.SelectedItem.Value +
        navigator.InnerXml = innerXml;


    That helper is already in the project, so you can just add the call right before the weight value is saved:


    The ExtensionWeightTrackHunger constant is used to uniquely identify the extension. Because there is a possibility for collision here, it would be a good idea to use a “<application>.<extension-name>” format. The constant that is currently in the project is incorrect – change it to “WeightTracker.Hunger”.

    In addition to the actual data stored in the extension (the ExtensionData property), there are a few other items that you can store:

    • Logo is the url of a logo to display with the extension.
    • Source is the source identifier.
    • Transform is the URL of a transform that converts the extension data into an HTML form.
    • Version is the version number of the extension

    We’ll follow our usual pattern in modifying our fetching code:

    First, add a “Hunger” header as the second-to-last entry.

    Then, we need some code to iterate over all extensions, similar to how we iterated over the related items. There is a helper in the project, but I don’t like the way it works any more, so we’ll use this code instead:

    string hunger = String.Empty;
    foreach (HealthRecordItemExtension extension in weight.CommonData.Extensions)
        if (extension.Source == ExtensionWeightTrackerHunger)
            XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
            XPathNavigator value = navigator.SelectSingleNode("extension/hunger");
            if (value != null)
                hunger = value.Value;

    Finally, add hunger to the call to AddCellsToTable(). Run the project and verify that it works.

    A Nicer Approach

    We can make things better by using a derived class for the extension.

    Add a new class to the project, and name it “Hunger Extension”. Visual studio will ask you if you want to put it in App_Code – tell it “yes, that would be lovely”.

    Replace the class with the following:

    using System;
    using System.Xml;
    using System.Xml.XPath;
    using Microsoft.Health;
    using Microsoft.Health.ItemTypes;

    public class HungerExtension : HealthRecordItemExtension
        static readonly string ExtensionSource = "WeightTracker.Hunger" ;

        string m_hunger;

        public HungerExtension()

        public HungerExtension(string hunger)
                       : base(ExtensionSource)
            m_hunger = hunger;
            Source = ExtensionSource;

        public string Hunger
            get { return m_hunger; }
            set { m_hunger = value; }

        protected override void ParseXml(IXPathNavigable extensionData)
            XPathNavigator navigator = extensionData.CreateNavigator();
            XPathNavigator hungerNode = navigator.SelectSingleNode("extension/Hunger" );

            if (hungerNode != null)
                m_hunger = hungerNode.Value;

        protected override void WriteXml(System.Xml.XmlWriter writer)

        public static void RegisterExtensionHandler()
            ItemTypeManager.RegisterExtensionHandler(ExtensionSource, typeof(HungerExtension), true);

    The class is pretty simple. The ParseXml() method pulls the data out of XML and puts it in the class, and the WriteXml() method does the opposite. The RegisterExtensionHandler() method registers this extension with the SDK, so that when it sees that extension, it creates an instance of our derived type instead of a generic HealthRecordItemExtension instance.

    Now that we have the class, it’s much easier to use our extension.

    First, add the call to register the extension before the weight values are loaded:


    Modify the code to fetch the hunger value to the following:

    string hunger = String.Empty;
    foreach (HealthRecordItemExtension extension in weight.CommonData.Extensions)
        HungerExtension hungerExtension = extension as HungerExtension;
        if (hungerExtension != null)
            hunger = hungerExtension.Hunger;

    Change the code to save the hunger to the following:

            new HungerExtension(c_dropDownListHunger.SelectedItem.Value));

    Run the application, and verify that it works. Then delete the unnecessary helper methods and string constant from default.aspx.cs

    Other resources:

    There is another set of pages where you can look at the schemas for the item types, and schemas for all the platform methods. We will be unifying these two sources in the future.

    Next Time

    Next time, we’ll talk about data filtering.

  • Eric Gunnerson's Compendium

    After SchooL chocLate cookies

    • 2 cups chocLate Syrip
    • 2 cups flour
    • 1/4 cup maLLases
    • 5 cups oatmeaL
    • 5 TabLespoons SaLt
    • 5 teaspoons BakingSoda

    Put OatmeaL, SaLt, fLour and Soda in bowl

    Stir in syrip and MaLLases

    Bake ten minits

    Temp 345

    Eric, age 7

    (I was cleaning out some old stuff this weekend, and thought I would share it with you)

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #9: Optional Authorization


    This week, we have a new customer request. One of our customers wants to track her mood on a daily basis. We can do this by using the Emotion data type, but after talking with our broader customer base, we find that some of them don’t want this information displayed by the application.

    What to do? What to do?

    Enter optional auth

    Optional auth allows different users to grant our application different amounts of data access. All users are requested to grant us the base auth for the application, but our application decides when to ask users for additional data access.

    We will use the specific access granted by a user to determine what information to query for and what to display in our user interface.

    Setting up our optional authorization rule

    Go to the application configuration center, pick your application, and add a new rule, named “Opt_Emotion”, make it optional, ask for Create/Read permissions, and choose the “Emotional State” data type. Save your rule.

    Determining type permissions

    We can ask the platform for information about our access to the Emotion data type with the following code:

    List<Guid> items = new List<Guid>();
    Collection<HealthRecordItemTypePermission> permissions =

    This code asks the selected record whether it has access to Emotion. If there is no access, the permissions collection will be empty.

    Since we’re only concerned with one rather than several types, I wrote a little wrapper to make our code a bit simpler. Put this at the beginning of Page_Prerender:

    HealthRecordItemTypePermission emotionPermission =

    If you look at the HealthRecordItemTypePermission class, you’ll see that it stores the permissions for both online and offline access. In our case, we want to look for online access.

    if (emotionPermission.OnlineAccessPermissions == HealthRecordItemPermissions.None)
        c_linkEnableMoodTracking.Visible = true;
        c_labelMood.Visible = true;
        c_dropDownListMood.Visible = true;
        PopulateDropDownFromEnum(c_dropDownListMood, typeof(Mood));

    Because I’m going to be defining the rule set, I know ahead of time that the user is either going to have enough access to Emotion for me to do what I want, or no access at all. I can therefore simply test whether there is any access to control my UI.

    It’s possible, however, for me to ask for read and write access separately, and if I had done that, I would need to check for specific permissions (Create, Read, Update, or Delete).

    It would probably be a good time to run the project to see what happens. There should be a link below the Save button that says “Enable Mood Tracking”.

    Asking the user for access

    You might remember when you first ran the application, you were redirected to HealthVault so that you could authorize access for the application. For optional authorization, we’re going to send the user back to that same page.

    But first, we’d like to explain to the user the advantages of providing us access. That is done with a landing page named AuthorizeEmotion.aspx.

    Here’s the code that will do the redirect:

    string TargetQuery =
    RedirectToShellUrl("APPAUTH", TargetQuery);

    The appid parameter must be set your application’s application id, and the onopt1 parameter is set to the name of the rule we want to ask for. It is possible to ask for multiple rules and to ask for offline access as well – the details are on the HealthVault Shell Redirect Interfaces page.

    Run your application, and choose the “Enable Mood Tracking” button, and click “Authorize”. When you get back to the authorization page, you will now find that it now asks for access to the Emotional State data type, with a checkbox next to it. Click the checkbox, approve access, and you’ll now find that the UI shifts into the “mood-enabled” mode.

    Storing and displaying Mood values…

    Storing and display Mood values is similar to the code we wrote to store the exercise values. We add the following code after we save the Exercise instance:

    Emotion emotion = null;
    if (c_labelMood.Visible)
        emotion = new Emotion(new HealthServiceDateTime(DateTime.Now));
        emotion.Mood = (Mood) Int32.Parse(c_dropDownListMood.SelectedItem.Value);

    and then modify the code that sets up the relationship:

                 new HealthRecordItemRelationship(exercise.Key));
    if (emotion != null)
                new HealthRecordItemRelationship(emotion.Key));


    Displaying mood values in the table

    The header on the table needs to change based on whether we are tracking mood or not:

    if (c_labelMood.Visible)
        AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI", "App Name",
                               "Minutes", "Mood", "&nbsp;");
        AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI", "App Name",
                               "Minutes", "&nbsp;");

    We add the following to our relationship-fetching code:

    Emotion emotion = relatedItem as Emotion;
    if (emotion != null)
        mood = emotion.Mood.ToString();

    after declaring “string mood” right below “string minutes”.

    And finally, we modify our code that adds the data to the table:

    if (c_labelMood.Visible)
        AddCellsToTable(c_tableWeight, weight.When.ToString(),
                   weight.Value.DisplayValue.ToString(), bmiString, appName, minutes, mood);
        AddCellsToTable(c_tableWeight, weight.When.ToString(),
                   weight.Value.DisplayValue.ToString(), bmiString, appName, minutes);

    With that code, the application should now support entering and displaying mood information.


    If we want to give the user the opportunity to turn off mood tracking, we can do it by using the same call as we used to authorize the access.

    Add a page named DeauthorizeEmotion with appropriate text and code, and then modify the main page code so that it shows the authorize or deauthorize link as applicable.

    Current Code

    To help keep your code in sync with mine, I’ve uploaded my current code to MSDN Code Gallery. You will need to change my source so that it uses your application ID rather than mine.


    I have a list of topics that I’m planning on covering, but if you have a suggestion for what you’d like to see, let me know.

    Next Time

    Next time, we’ll be looking at how to store hunger information in our application.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #8: Related items


    Our current application allows users to track their weight, but some of our users also want to track the time they spend walking. In this episode, we’ll extend our application to store and display that information.

    We will be storing that information in the Exercise type. First, we’ll need to head off to the Application Configuration Center (there’s a link at the bottom of the HealthVault Application Manager if you forget the URL…)

    Locate your application, and look at the online access that is currently defined. We could add a new rule named “Exercise”, but that would get unwieldy pretty quickly with lots of types. Instead, we are are going to group our rules based upon the type of access required. What we are defining right now is known as the application’s “base auth”, so we’ll put that concept in our names to make it easier later, when we explore the other kind of auth (if you’re too excited to wait, it’s called “optional” auth…)

    1. Edit the Weight rule. Change the name to “Base_All”.
    2. Add access to Exercise to this rule.
    3. Rename the Height rule to be “Base_read”.

    After you save the configuration (and perhaps wait a short time for the new configuration to be activated), run the application.

    You will be redirected to re-authorize the application, since your application is now asking for more data access than you had previously authorized it to have.

    That can make things a bit inconvenient (and confusing) for your users. You deploy a new version of your app that uses more types, and they have to reauthorize. The answer to that is the aforementioned optional auth, which I promise we’ll cover very soon.

    Now we can modify our code to record that exercise information.


    A little bit of housekeeping first, to fix a bug that you might have noticed. If you enter a new weight value, it doesn’t show up right away. This is because of a mistake I made when I wrote the first version.

    When the user enters a new weight, the data is posted back to the asp page, and Page_Load is called, then c_buttonSave_Click, then Page_Prerender, in that order (other stuff happens too). Which means that we’ve already rendered out the “current” set of information before we add new new value, which is why it doesn’t show up.

    The fix is to take all of the code that is currently in Page_Load, and move it into Page_Prerender.

    I assure you that this bug was in the code to provide a chance for you to debug your code, and certainly not an oversight from when I wrote the original code.

    Saving Exercise Information

    Go to default.aspx, and make label2 and c_textboxWalkingTime visible. This provides the UI that users use to enter their walking time.

    We’ll start by creating an Exercise instance:

    Exercise exercise = new Exercise();

    Next, we need to record when the exercise happened. We do this with the following:

    DateTime now = DateTime.Now;
    ApproximateDateTime approximateDateTime = new ApproximateDateTime(
        new ApproximateDate(now.Year, now.Month, now.Day),
        new ApproximateTime(now.Hour, now.Minute, now.Second));

    exercise.When = approximateDateTime;

    That’s an ugly bit of code, but that’s what you have to write right now. Our next release will let you write this as:

    exercise.When = new ApproximateDateTime(DateTime.Now);

    so you might want to give that a try.

    Now, we want to store the number of minutes that our user walked:

    int minutes = Int32.Parse(c_textboxWalkingTime.Text);
    exercise.Duration = minutes;

    We’re still missing an important piece of data – the kind of exercise. We would like to store this information so that programs can make decisions based on the specific activity. That can easily be done by defining a set of different activities (which is known as a “vocabulary” in HealthVault, and referencing one of those with the exercise.

    But that would miss an important piece of data – what the user said the activity was. Perhaps they want to enter “race walking” or “fitness walking”, or “walk in the park” and have the system show that as the activity when it displays the exercise information.

    To accommodate both of those uses, HealthVault uses a concept of a codable value, which is similar to the measurement type discussed in an earlier episode. It stores a Text value – which is whatever the user or program thinks it should be – and one or more coded values, which provide the specifics that programs would read.

    We’ll start by defining the CodedValue part. Looking at the docs for Exercise.Activity, we find it recommends the exercise-activities vocabulary (we could also have looked in the list of vocabularies).

    Each vocabulary item has a code, a display text, and an abbreviation. So, to code to walking, we use the following coded value:

    CodedValue codedValue = new CodedValue(“Walking”, “exercise-activities”);

    Where "Walking” is the code and “exercise-activities” is the vocabulary.

    We’ll use that to create the whole codable value:

    exercise.Activity =
        new CodableValue("Walking", new CodedValue("Walking", "exercise-activities"));

    In this case the Text and the codable value are the same, but in most cases the code is going to be considerably more terse than the Text value, or it may be a numeric value.

    If it was important to our application to store more information, or if we wanted to refer to more than one vocabulary, we could add additional coded values to the codable value. This is useful if there is more than one standard set of codes for a particular property.

    The codable values that are stored are not validated by the platform, which gives applications the flexibility to code to vocabularies that are not on the platform. We’d appreciate it, however, that you let us know if you’re coding to a vocabulary that you think should be on the platform.

    After all of that, we can save the Exercise instance to the record:



    In the last bit of code, I created the Exercise instance and then set the properties. That works fine, but all of the types in HealthVault declare constructors that take all the required values as parameters, and using that constructor is a good way of making sure you set all the required properties. Using that approach, our code would look like this:

    DateTime now = DateTime.Now;
    ApproximateDateTime approximateDateTime = new ApproximateDateTime(
        new ApproximateDate(now.Year, now.Month, now.Day),
        new ApproximateTime(now.Hour, now.Minute, now.Second));

    Exercise exercise = new Exercise(approximateDateTime, 
                     new CodableValue("Walking",
                                                new CodedValue("Walking", "exercise-activities")));

    int minutes = Int32.Parse(c_textboxWalkingTime.Text);
    exercise.Duration = minutes;


    Related Items

    There’s a problem in the code that I just wrote. The Exercise instance and the Weight instance were entered at the same time by the user, but that relationship isn’t stored in HealthVault. This is going to complicate our display code considerably, as we have no easy way of finding the Exercise instance that goes with a specific weight.

    We’ll use the Related items feature to connect them together.  We’ll simply add the Exercise instance to the related items list of the weight before we save it to the database:

    weight.CommonData.RelatedItems.Add(new HealthRecordItemRelationship(weight.Key));

    Related items is pretty low-tech – the id of the related object is merely saved on the object. The platform doesn’t provide referential integrity or any of that database stuff, so applications must be prepared to come across related item links that refer to items that aren’t accessible to the application.

    Displaying the Exercise information in the table

    Whenever we fetch a weight, we want to see if there is a related exercise instance. Here’s the code that we’ll use:

    string minutes = String.Empty;
    foreach (HealthRecordItemRelationship relationship in weight.CommonData.RelatedItems)
        if (relationship.ItemKey != null)
            HealthRecordItem relatedItem =
                HealthRecordItemSections.Core | HealthRecordItemSections.Xml);

            Exercise exercise = relatedItem as Exercise;
            if (exercise != null)
                minutes = exercise.Duration.ToString();

    This code walks through all the related items for an instance, and if there’s a key, it fetches the related item instance. It checks to see if the item fetched is an exercise, and if it is, formats the duration.

    The task of adding a new column named “Minutes” to the table and the minutes value to the body of the table is left as an exercise to the reader.

    Other Stuff

    There are a few other topics that out of scope of this episode, but worth mentioning anyway.

    Exercise is the new version of the AerobicSession type. Because of the type of data they store and the differences between the types, applications that will process AerobicSession data will likely want to handle it separately from Exercise data.  There is more information on this issue here.

    There is a second method of relating items together known as client ID, which is used by HealthVault connection center when it needs to link instances together (related items doesn’t work for it because of some architectural issues). I’ll cover client IDs in the future.

    Next Time

    Next time, we’ll do something with optional auth.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #7 – Data provenance



    After our application is “in the wild” for a while, we receive some strange reports from our users.

    Some of the weight data being displayed appears to be suspect, and after investigation we find out that some of our users are also running an application named WeightOptimizer.

    Download and set up the Weight Optimizer application now, “optimize” one weight, and delete another. Run WeightTracker and look at the results.

    Now we’re going to figure out what to do in response to what is happening.


    One of the big values of HealthVault is that data can come from many different sources, and in general applications should use all data that is present in the record. However, some applications may want to determine the provenance of a specific piece of data, and that’s what this post is about…


    What we need to do is modify our application so that we fetch the source of the data, and then use that information to decide what we are going to do with it.  The information we want is in the Audits section, so we modify our fetching code to the following:

    HealthRecordFilter filter = new HealthRecordFilter(Weight.TypeId);
    filter.View.Sections |= HealthRecordItemSections.Audits;


    The information about the current state of the object is in the LastUpdated property, which is of type HealthServiceAudit. There is lots of interesting information here, but we’re going to concentrate on identifying a specific application. We’ll just add a column to the table to show the application name. Here’s our display code:

    AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI", "App Name", "&nbsp;");
    foreach (Weight weight in weights)
        double bmi = weight.Value.Kilograms / (height.Value.Meters * height.Value.Meters);
        string bmiString = String.Format("{0:F2}", bmi);

        string appName = weight.LastUpdated.ApplicationName;

        AddCellsToTable(c_tableWeight, weight.When.ToString(),
                        weight.Value.DisplayValue.ToString(), bmiString, appName);
        AddLinkToEditPage(c_tableWeight, weight.Key.Id);

    A real application would likely want to implement a more sophisticated scheme. It might look at the audit information, and use the application id to put the information into classes such as the following:

    • Data the application wrote itself
    • Data from a list of applications tracked by this application
    • Device data that was uploaded through HealthVault Connection Center
    • Data from all other applications

    The classification would then be used to control application behavior.

    In addition to the information contained in the Audit fields, the HealthVault platform also supports signing individual data items with a digital signature that can later be used to help establish provenance. I hope to discuss digital signatures more in a future post.

    Next Time

    Next time we’ll add exercise tracking to WeightTracker.

  • Eric Gunnerson's Compendium

    Age of Halo


    My daughter downloaded the demo for Halo Wars a few days ago, and I spent a few hours playing it recently. It's from Ensemble, responsible for the "Age of <X>" (Empires I, II, III, and Kings), and it's similar enough that I've named it "Age of Halo".

    It's a pretty standard approach - build buildings, do research, train fighters, though there are some interesting constraints they've imposed this time around that I think will make the gameplay a bit different.

    I'm definitely going to pick it up when it comes out on March 3rd.  

  • Eric Gunnerson's Compendium

    25 Random things about Eric...


    I did this for facebook, but thought I'd post a link here.

    25 Random things about Eric

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #6 – Fixing a mistake



    After we’ve released our application, some of our users complained that they accidentally entered an incorrect weight, and would like to have a way of fixing it.

    We will therefore extend our application to be able to update a weight. We’re going to do that by creating a separate edit page (editing in-line would be nicer, but this way is simpler).

    For the update page to know which weight it should be editing, we need a way to uniquely identify a specific weight instance. Every item that is stored in a HealthVault record has a property named Key of type HealthRecordItemKey. That type has two properties:

    • A guid named Id that uniquely identifies the instance.
    • A guid named VersionStamp that I’ll discuss in a little bit.

    For each Weight that is stored in our table, we’ll create a hyperlink to the update page that passes the Id. We do this by placing creating a HyperLink object and adding it to the table, and in this case there’s already a helper in the project that does that. So, we add the following after the call to AddCellsToTable():

    AddLinkToEditPage(c_tableWeight, weight.Key.Id);

    We also add a blank column header so the table doesn’t look weird:

    AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI", "");

    That will give us a link to UpdateWeight.aspx. If you open that file, you’ll see that it has a few labels for displaying the current data, a place to enter the new weight, and an Update button.

    We need to write the code to fetch the Weight instance that the user wants to edit. We do this in the Page_Load() method in UpdateWeight.aspx.cs. First, we convert the Id from a string to a guid and stash it away for later:

    _idToUpdate = new Guid(id);

    Now we fetch the Weight instance. In our previous code, we used a filter to find the set of items that met a specific set of criteria, but in this case we’re looking to get a specific instance of the Weight type. We do that by calling GetItem():

    Weight weight = (Weight)
          PersonInfo.SelectedRecord.GetItem(_idToUpdate, HealthRecordItemSections.Xml);

    The _idToUpdate argument specifies which item we want to fetch, and the second one specifies what part of the object to fetch.

    Each HealthVault instance has a fair amount of data and metadata associated with it, and for performance reasons, applications should typically fetch only a subset of the sections.

    The sections are defined by the HealthRecordItemSections enumeration, which has the following items in it:


    This section contains information about when an item was created or updated, which application and person performed the update, and when it happened. If it is passed, the Created and LastUpdated properties on the object will be populated.


    This section contains the core information for the object, including the EffectiveDate, State, Flags, IsPersonal, IsDownVersioned, and IspVersioned properties.


    An application can use the EffectivePermissions information to determine what operations it is authorized to perform on an object.


    This section contains information that is either auxiliary to the main purpose of the object, or information that is large and would not always be needed.


    This section is similar to OtherData but provides stream-based access to the information


    This section contains the HealthRecordItemSignatures property.


    This section contains any textual tags that have been applied to the instance.


    This section contains the type-specific information for the type. You will need to fetch this if you want to use any properties defined on the type.

    The section information can also be specified on filtered queries using HealthRecordFilter.View.Sections.

    Displaying the data

    Now that the data is fetched, we can populate the values into the UI controls:

    c_labelInstanceId.Text = _idToUpdate.ToString();
    c_labelWeight.Text = weight.Value.DisplayValue.ToString();

    Note that for the weight, we’re displaying exactly what the user originally entered by using the DisplayValue property.

    Updating the weight value




    The last task is to update the weight item, which uses a slight variation of the code we wrote to save the value in the first place. This goes in the MakeUpdate() method:

    Weight weight = (Weight)
        PersonInfo.SelectedRecord.GetItem(_idToUpdate, HealthRecordItemSections.Xml);

    int weightInPounds = Int32.Parse(c_textboxNewWeight.Text);
    weight.Value.Kilograms = weightInPounds / 2.204;
    weight.Value.DisplayValue = new DisplayValue(weightInPounds, "pounds");



    One of the challenges in any system that allows multiple applications to read/write data at once is maintaining data integrity. Specifically, with the above code, we need to make sure that that nothing in the instance changes between the time we fetch the value and when the update happens.

    This is where the VersionStamp comes in. Whenever an instance is stored in HealthVault, the system creates a VersionStamp to store with it. In the update code, when the weight is fetched, it gets the current value of the VersionStamp. When UpdateItem is called, that version stamp is passed back to the platform. If it matches the current version stamp, then the platform knows that the object has not been modified, and the update operation is successful. If the version stamps do not match, the call to UpdateItem() will throw an exception, and the application will need to implement appropriate recovery methods to handle it.

    After the update is performed, the code redirects back to the application’s main page.

    Next time

    Next time, we’ll talk about some perplexing data that is showing up for some of our users.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #5 – Do I weigh too much?



    A common question asked by people is “do I weigh too much”, so we’re going to add the calculation of BMI to our application.


    The question of what a person’s desirable weight is – or even if there is a desirable weight – is one with lots of opinions. I chose to do BMI here because it’s simple and it works well, but it’s well known that BMI doesn’t work that well for a lot of people.

    For example, my BMI (at 6’ 2” and 170 pounds) is 21.8, which puts me in the middle of the normal range. I would still be normal (at least according to the BMI ranges) even if I weighed 145 pounds, but I’m pretty gaunt if I get down to 165.


    The formula for BMI is quite simple (which is one reason it’s used so often):

    BMI = weight (Kg) / (height (m) ^ 2);

    Let’s write some code in Default.aspx.cs.

    You will remember that when we configured our application, we asked for access to read the Height values, so we won’t have to update the configuration this time.

    Last time we fetched values, we did the whole bit of creating the HealthRecordSearcher and the HealthRecordFilter, but this time we’re going to use a helper method to simplify the code:

    Height height = GetSingleValue<Height>(Height.TypeId);
    c_labelHeight.Text = height.Value.DisplayValue.ToString();

    We also need to make the height value visible in the user interface. Flip in the designer for default.aspx, and set the visibility of the Height and c_labelHeight controls to true. Or, you can just edit the layout code directly if you wish.

    Now, to add the BMI value to the table. We add a new header cell:

    AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI");

    And we’ll add the code to calculate and display the bmi to our display loop:

    double bmi = weight.Value.Kilograms / (height.Value.Meters * height.Value.Meters);
    string bmiString = String.Format("{0:F2}", bmi);

    AddCellsToTable(c_tableWeight, weight.When.ToString(),
                            weight.Value.DisplayValue.ToString(), bmiString);

    Now, when we run the code, we’ll get our weight and BMI values. Or, it will blow up if you haven’t entered a height value yet. If that’s the case, you can enter one through the HealthVault Shell.

    Here’s the full Page_Load() method:

    protected void Page_Load(object sender, EventArgs e)
        HealthRecordSearcher searcher = PersonInfo.SelectedRecord.CreateSearcher();

        HealthRecordFilter filter = new HealthRecordFilter(Weight.TypeId);

        HealthRecordItemCollection weights = searcher.GetMatchingItems()[0];

        Height height = GetSingleValue<Height>(Height.TypeId);
        c_labelHeight.Text = height.Value.DisplayValue.ToString();

        AddHeaderCells(c_tableWeight, "Date", "Weight", "BMI");
        foreach (Weight weight in weights)
            double bmi = weight.Value.Kilograms / (height.Value.Meters * height.Value.Meters);
            string bmiString = String.Format("{0:F2}", bmi);

            AddCellsToTable(c_tableWeight, weight.When.ToString(),
                            weight.Value.DisplayValue.ToString(), bmiString);

    Next Time

    In the next episode, we’ll learn how to update data...

  • Eric Gunnerson's Compendium

    The Omnificent English Dictionary in Limerick Form


    A very nice collection of definitions, all done in limerick form.  


  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #4 – Storing and retrieving weights


    We are now ready to make our WeightTracker application do something useful.

    That something useful is composed of two stories:

    • The user enters a weight, and it’s stored to the user’s HealthVault record
    • The weight measurements in the user’s record are displayed

    We’ll do them in order.

    Entering and storing a weight

    Looking at default.aspx, you will find that it’s prepopulated with some controls that we’ll be using in the tutorial. Some of the ones that we don’t need yet are marked as invisible. For now, just pretend that the ones that aren’t visible aren’t there, and nobody will get hurt.

    For this story, we’ll be using the c_textboxWeight for the user to enter the weight, and the c_buttonSave for the user to press to save the weight.

    Switching to the code file (Default.aspx.cs), we see that there’s a click handler c_buttonSave_Click() where we’ll write the code to save the weight value to the user’s record.

    First, we’ll get the weight value that the user entered and convert it to an integer:

    int weightInPounds = Int32.Parse(c_textboxWeight.Text);

    Then we’ll create an instance of the Weight type, which is (surprise) the type you use to store weights.

    Weight weight = new Weight();

    Now, we need to put the weight value from the user into the weight instance. But we have a problem.

    To make weight values interchangeable between applications, the Weight data type stores weight values measured in kilograms. But most users in the US would prefer to see their weight displayed in pounds.

    To fix this, we could just tell applications to perform the appropriate conversions to and from whatever unit they want to use, but that may cause problems with round-trip conversions:

    3 miles -> 4828.031 meters

    4828.031 meters –> 2.99999938 miles

    HealthVault solves the problem by storing measurements in two separate formats – the exact way the user entered the value, and the value stored in the standard units. The first one is used when an application needs to display a value, and the second one is used to perform calculations.

    Back to our code. We’ll start by storing the weight using our standard measure:

    weight.Value.Kilograms = weightInPounds / 2.204;

    And then we’ll set what we call the DisplayValue, which is the value the user entered.

    weight.Value.DisplayValue = new DisplayValue(weightInPounds, "pounds");

    Now that we’ve stored the value in the weight instance, we need to save it to the appropriate HealthVault record. We do that with the following code:


    HealthVault organizes data into records, where each record holds data for a specific person. Data access is always performed through a specific person’s login. So…

    PersonInfo corresponds to the person who is currently logged in. When they chose to authorize an application, they selected a specific record to authorize, and that is returned to the application in SelectedRecord. So PersonInfo.SelectedRecord is shorthand for “the record the user chose”.

    It is possible for the application to redirect to the HealthVault shell to switch to a different record, or for an application to deal with more than one record at the same time, but that’s beyond what we’re trying to do right now.

    Querying and displaying weights

    Now that we’ve figured out how to save weights, we need to write some code that will fetch the weights that we’ve entered and display them in a table. We’ll put that code in the Page_Prerender() method.


    We use Page_Prerender rather than Page_Load because any events – such as the one fired when the user enters a new weight – occur after Page_Load but before Page_Prerender. So, if we put our code in Page_Load, newly entered weights would not show up.


    First, we need a way to query the current record. This is done through the HealthRecordSearcher class, which we can get from the selected record:

    HealthRecordSearcher searcher = PersonInfo.SelectedRecord.CreateSearcher();

    Next, we need a way to specify which items we want to read from the record. That is done using the HealthRecordFilter class. It has a number of options that can be used to control what items it returns – we will use it in the simplest way by specifying the type that we want returned:


    HealthRecordFilter filter = new HealthRecordFilter(Weight.TypeId);


    Now we want to send that request over to the HealthVault server, and get the weight items back:


    HealthRecordItemCollection weights = searcher.GetMatchingItems()[0];



    You may have noticed that HealthRecordSearcher.Filters is a collection of filters rather than a single filter. If you want to do more than one query in a single request, you can add multiple filters to the searcher object, and they will all get executed in one batch.

    When you call GetMatchingItems(), you get a collection of result collections, with one result collection for each filter. Since there’s only one filter here, we look at the first collection only.

    Executing multiple filters at once may improve the performance of querying.


    Finally, we need to walk through the returned weight items and display them. We do that with the following code (including some canned code to do the ASP.NET table manipulation):

    AddHeaderCells(c_tableWeight, "Date", "Weight");
    foreach (Weight weight in weights)
        AddCellsToTable(c_tableWeight, weight.When.ToString(), 

    The two helper methods make adding items to the table a little easier. Note that we are using the weight DisplayValue to show to the user.

    Next Time

    In the next episode, we’ll add some calculations to our application…


  • Eric Gunnerson's Compendium

    New computer


    I've shot a fair number of pictures this last year - mostly of my daughter's sports. My camera is a Canon 40D, and I generally use my 70-200mm F4L lens. The camera works well and is better than I am.

    I shoot all my photos in RAW format, which basically means you get the information before the camera does any post-processing (white balance, exposure, sharpening, etc.) I then use Lightroom 1.4 to make the adjustments that I want, and then export them to jpeg and upload them to smugmug.

    I'll typically shoot a full card of about 300 exposures at a game, and then when I get back, I need to delete the shots I don't like, crop all the keepers, and then do the adjustments I want.

    My current laptop is pretty ancient and is slow at doing this, and I've wanted to start using Lightroom 2.2, which is nicer but takes more resources.

    After a bit of thought, I decided that I'd put together a new system for our office and do photography on that rather than getting a new laptop. My plan was to build a new office system and then get a mid-range laptop rather than trying to get a pricey laptop that did everything I wanted.

    I don't keep up on processors as much as I used to, so I set of to do some research. I started at Ars Technica, and looked through their current system recommendations as a starting point.

    The first choice point was the processor. I've traditionally gone with AMD on price/performance and though I considered the Intel dual or quad cores, I ended up settling on an AMD Athlon dual core running at 3.1 GHz ($72.99). The quad-core Phenom looks interesting - and Lightroom does a good job with multiple cores - but it isn't that fast yet. I bought the retail processor which came with a nice quiet fan to make things easier.

    For a motherboard, I got the ASUS M3A78-EM ($78.99). It has pretty much everything I want onboard, with decent but not great graphics, and it has the AM2+ socket, so when the Phast Phenoms are available, I'll just be able to slot one right in. The motherboard supports 8G of main memory, and it's full of DDR2 1066 memory from Kingston ($91.98).

    For storage, there are two Samsung Spinpoint F1 750G drives ($159.98). I like having multiple disks so I can put system/swap on one and application data on another, and for Lightroom you can put the catalog on one drive and the pictures on another, spreading your I/O out.

    Add in a DVD burner ($26) and a nice Inwin case ($65).

    In the old days, I'd talk about all the cards I'd put in it, but the motherboard has a ton of stuff built in. I'll likely pull my Soundblaster Audigy out of the old office system and put it in the new one.

    Oh, and a combination floppy disk and card reader, so that I can pull the pictures off the card as fast as possible ($25).

    Putting the system together was pretty simple - a bit tight around the drives but not bad. The Inwin case came with a really nice adapter for all the front panel controls. You plug in the separate cables for power light, HDD light, power switch, reset switch into this little header that's labeled, and then the header plugs into the motherboard. Same for the USB cable from the card reader.

    And, of course, SATA is more than a little easier to put together than IDE.

    The system started fine, and was treated to an install of Vista Ultimate, 64bit version. That went fine, thought I needed to use the motherboard driver disk to get everything up and running.

    Lightroom 2.2 went on tonight, and the system works very nicely, even with the adjustment brush feature which is known to be pretty slow, and I haven't gotten around to putting the catalog on a separate disc.

    Total is somewhere around $600, which is pretty good. I still need to get a calibrator to calibrate my monitor so I'm seeing the right colors, and then it's time to move over all the other apps and data.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #3: Configuring our application


    Now that we have HelloWorld set up and running, we want to move on to developing the real application. We’ll start with a shell application and add to it as we go.

    Download the WeightTracker shell, and open the project in Visual Studio. Register the certificate using the same process you used in the previous tutorial. Add a reference to the following HealthVault assembiles in c:\program files\microsoft healthvault\sdk\dotnet\assemblies:

    • Microsoft.Health.dll
    • Microsoft.Health.ItemTypes.dll
    • Microsoft.Health.Web.dll

    Run it, and you will be taken to the HealthVault authorization page for the application. Note that it’s specific to this application – it has its own name, logo, description, and set of requested types.

    It is possible to continue in the tutorial using the configuration that comes with WeightTracker, but since configuration is an important part of HealthVault applications, I recommend that you create your own configuration. That’s what we’ll be doing in this part of the tutorial.

    Creating a new certificate

    When we were working with Hello World, we had to register the application certificate on our system, and we did that through the MMC utility.

    This time, we need to create a certificate, register it on our system, then register it with the HealthVault platform. It’s possible to do the work by hand, but we’re going to use a utility that ships with the SDK to do this.

    Go to Start-> All Programs –> Microsoft HealthVault –> SDK –> HealthVault Application Manager. If you are running Vista, you’ll need to run as administrator.

    You should see the initial application manager screen, and it should list the HelloWorld Sample certificate that you registered in the last part of the tutorial, and it may list other sample applications you have used.

    The Application Name isn’t stored as part of the certificate – it is only stored by the ApplicationManager application. The application knows the names of some of the sample applications, which is why they show up.

    If you check the “Show Unnamed applications” checkbox, you will see the WeightTracker certificate pop up. You can verify which one it is by matching the application ID (defined in web.config) with the certificate name.

    We will create a new certificate by clicking the appropriately-named button. This will bring up a dialog that asks you to enter a name for the application.

    I chose to call mine “Weight Tracker Tutorial”, since that’s the name of the application we’ll be writing. You can use the same name or something else, like “Pizza Joe’s spicy vegetarian”.

    The main list should refresh and you should see the new certificate listed. When we generated a certificate, it was created with both a private and a public key, and they’re both in the certificate store. The public key is something that we’ll send off to the HealthVault platform so it can use to verify items signed with the private key. Public keys are typically passed around as .cer files.

    The private key isn’t something that we should be emailing around, because anybody who has it can pretend to be us. Application manager does allow you to export both the private and public keys in a .pfx file, in case you want to run the application on another server.

    The wikipedia articles on public key cryptography and digital signatures are good introductions to this area if you would like to know more. There is also the cryptography overview on MSDN.

    Registering a certificate with the HealthVault platform

    To register a certificate, right-click on it and choose “Upload certificate”.

    This will package the certificate’s public key and the application name (if present) into a request, and send it off to the HealthVault application configuration center. It will then launch your browser to the app config center.

    The app config center is a HealthVault application, and access to the configuration of a specific application is limited to a single HealthVault account. When you authenticate, you should use an appropriate account that works for what you are doing – using a shared account when multiple people need to be able to access and modify an application’s configuration.

    Once you have authenticated, you will see a list that contains your new application, with the name that you chose, and the generated application id. Click on your application.

    You will see the Information page for your application. Here, you set the name, description, and other items that show up on the authorization page, including the logo.

    Configuring an application’s data access

    We’ll start by configuring the data access that we’ll need to get started.

    There are two kinds of access that an application can request. Online access provides access when the user is running your web application, and is what we’ll use in the tutorial. Offline access provides access whenever the application wants access, and is typically used to synchronize information between HealthVault and the application.

    Offline access is something users are more careful about granting, especially to groups that they don’t trust, so your application should try to use online access whenever possible.

    Click on the “OnlineAccess” tab. To make organization easier, data access is grouped into rules. Choose “add rule”, to bring up the rule editor.

    Here you need to give a name for the rule (which isn’t user-visible, so you can name it whatever you want), and a “why string”, which is the justification that is given to the user on the page where they decide whether to grant access to your application. Good why strings are required before you can go live, and if you put some thought into it at this point, things are much easier later on.

    I’ll call this rule “Weight”, because that’s what we’re going to ask for. For the why string, I thought of a few possibilities that we could use:

    1. Because we need to access your data.
    2. Because the application needs access to work correctly.
    3. WeightTracker uses access to your Weight measurements to help you effectively manage your weight.
    4. All your weight are belong to us.

    Which one is best? Please write 500 words explaining why, and have it for me on Monday.

    The key here is that the why string is displayed to the user, and it needs to be something that a) the user understands and b) explains the benefit of granting access.

    For permissions, I choose “All”, because I want to be able to perform all operations on Weight measurements (create/read/update/delete) , and then I choose the “Weight Measurement” data type from the list, and pick “Save”. That gives me my first rule.

    I add a second rule:

    Rule name: Height
    Why string: Weight Tracker uses your height to help determine whether your weight is appropriate.
    Permissions: Read
    Data types: Height Measurement

    Note that I only specified Read access, rather than asking for access that I don’t need. Your application’s access should always be as minimal as possible – don’t ask for access that you don’t need.

    You will also need to delete the rule for “Personal Image”.

    Now that we’ve done that, the platform configuration is complete. All that is left is to configure the application to use the new application ID.

    Configuring the application to use a new certificate

    To modify the application, we need to update the application id in web.config file.

    In application manager, right-click on your new certificate, and choose “copy certificate name to clipboard”. Switch over to Visual studio, open the web.config file, and look for the “ApplicationId” entry. You will find:

    <add key="ApplicationId" value="f36debe2-c2a3-434a-b822-f8c294fdecf9" />

    That’s the one that the application is currently using. On startup, the application finds this string, prepends “WildcatApp-“ to it, and then uses that string to search for a certificate to use.

    Duplicate the app id entry, and comment one of them out. Paste in your new application ID for the value in the one that isn’t commented out, remove the “WildcatApp-“ part, and save the file.

    Here’s what I typically do:

    <add key="ApplicationId" value="1b8cbb19-a9ed-4ebc-b498-6ae3d0ed44d7" />

    <!—applications ids
        my key
    <add key="ApplicationId" value="1b8cbb19-a9ed-4ebc-b498-6ae3d0ed44d7" /> |
        original key
    <add key="ApplicationId" value="f36debe2-c2a3-434a-b822-f8c294fdecf9" />

    At this point, you should be able to run your application, and get the authorization screen that matches the information that you entered in application configuration center.

    I like to keep another application ID around (usually the HelloWorld one) so that I can easily switch to it to see if I’m running into problems due to my application configuration.

    Next Time

    Next time, we’ll be writing some code.


  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #2: Hello World


    In this post, we’ll create an account on the HealthVault system, open up the HelloWorld sample application, and verify that it works on our system.

    There are two live HealthVault platforms.

    • A developer platform at This platform is intended to store test data rather than real consumer data, and is the one that should be used to develop an application. When an application is all done, there is a process to deploy (aka “go live”) with the application, and it will then be able to run against…
    • The consumer platform (which we sometimes confusingly refer to as the “live” platform) lives at

    All of our tutorial examples will be talking to the developer platform.

    Examine the source code

    Start Visual Studio, then open the HelloWorld application at C:\Program Files\Microsoft HealthVault\SDK\DotNet\WebSamples\HelloWorld\website.

    In the solution explorer, expand Default.aspx and double-click on default.aspx.cs. This shows the code for the main page. Notice that the page class is derived from HealthServicePage – that class handles the initial communication handshake between your application and HealthVault, sending the user to the right page to log into the system, etc. That all happens behind the scenes before the Page_Load handler is called.

    Open web.config, and browse through it. If you find the following line:

        <sessionState mode="InProc" cookieless="true"/>

    change it to:

        <sessionState mode="InProc"/>

    ApplicationId specifies a GUID that uniquely identifies a specific application to the platform. ShellUrl and HealthServiceUrl define which instance of the platform to talk to.

    There’s also a proxy setting at the end of the file – if you are running on a network with a proxy server, you will need to change this so that the application can get outside the firewall.

    Run the application

    Hit <F5> to start the program in the debugger.

    That will build the solution, start up the development web server, and start debugging default.aspx. A browser session will open up, and you’ll find yourself on the login page for the HelloWorld application.

    All authentication and authorization in HealthVault applications is performed by a set of web pages that live on the HealthVault server. These web pages are collectively known as the “HealthVault Shell”.

    When you ran the application, the startup code in HelloWorld realized that it didn’t know who the current user was, and redirected off to the appropriate HealthVault shell page.

    At this point, you will need to create a test HealthVault account. For authentication, you can either use Windows live or Live ID. If you need to create an authentication account – and for test purposes it’s probably a good idea not to use an account you use for something else – go do that now.

    Once you’ve created that account, enter the credentials on the login screen. You will be prompted to create a HealthVault account, and then (when you click continue), will be prompted to authorize the Hello World application to access the information in your record.

    Before an application can run against the HealthVault platform, it must be configured on that platform. That configuration stores some descriptive information about the application (name, etc.), and also the precise data type access that the application is required. For example, an application that tracks a person’s weight might need to be able to store and retrieve weight measurements, but only read height measurements.

    The authorization page that you are currently looking at details this information for the user, who can then make a decision about whether to grant the application that access. This page is atypical because the Hello World application asks for access to all types to make things more convenient, but real applications will only specify the subset of access required.

    Choose “approve and continue”, and you will be redirected back to a page on your system.

    This will be a page that says “Server error in ‘/website’ application. If you dig a little more, in the exception text you will find:

    SecurityException: The specified certificate, CN=WildcatApp-05a059c9-c309-46af-9b86-b06d42510550, could not be found in the LocalMachine certificate store,or the certificate does not have a private key.]

    Every time an application runs, it needs to prove its identity to the platform through a cryptographic signature. To do this, it needs a private key on the machine where the application is running. It will use that key to sign the data, and the platform will then verify the signature using the public key that was registered as part of the application configuration process.

    The Hello World application is already configured on developer platform, so we just need to register it on the client.

    Register the certificate

    To do this, we’ll need to get the certificate into the local machine’s certificate store. Go to the location on disk where HelloWorld lives, go to the cert directory, and you’ll find a .pfx file, which contains both the public and private keys.

    Start up the certificate manager using the following shortcut:

    C:\Program Files\Microsoft HealthVault\SDK\Tools\ComputerCertificates.msc

    Right click on certificates, choose “All tasks”, then “Import”. Specify the .pfx file at:

    C:\Program Files\Microsoft HealthVault\SDK\DotNet\WebSamples\HelloWorld\cert\HelloWorld-SDK_ID-05a059c9-c309-46af-9b86-b06d42510550.pfx

    And then hit next repeatedly and finish. That will finish the import of the certificate.

    If you use a proxy to get to the internet and there is a password associated with it, you may need to modify the config file for it. In the sdk/tools directory, find ApplicationManager.exe.config, and add the following:

    defaultProxy enabled="true" useDefaultCredentials="true">
    proxy usesystemdefault="True"/>

    At this point, you should be able to re-run the application (or just hit F5 in the browser), and the HelloWorld application should then work. Note that the certificate is only accessible for the user who imported the certificate – access for other accounts (such as IIS) can be granted through the winhttpcertcfg utility (also in the tools directory), or through a utility that we’ll discuss in the future.

    Next time, we’ll start on our application itself.

    Introduction to HealthVault Development #3: Configuring our Application

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #1: Introduction


    Welcome to the tutorial. In this tutorial, we will develop a HealthVault application from scratch.

    My intention is to add new tutorial chapters on a roughly weekly basis, though I have a few ones queued up and already to go.

    If you haven’t located the HealthVault Developer Center on MSDN, start by spending some time there. You can find a link to the SDK on the left side of the page. Download the SDK and install it.

    You will also need to have Microsoft Visual Studio installed on your machine (either 2005 or 2008). IIS is optional for development but may be useful for testing.

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #0: Background


    Coding without a net

    Over the years, I’ve attended a number of talks that show you how easy it is to use a new component, using canned projects, pre-written code that is cut-and-pasted in, and contrived scenarios.

    In the early years of .NET, I saw a different sort of talk (which I believe was done either by Scott Guthrie or Rob Howard) – one that started with File->New project, and just involved coding from scratch. It was very impressive, because you could see exactly what was going on, and you knew it was as easy (or as hard) as it looked. I’ve come to call this approach as “coding without a net”, which I will gladly take credit for coining despite the fact I’m sure I stole it from somebody.

    In the spring of 2008, I set out to write such a talk for HealthVault, to be presented at TechEd 2008 in late May and the HealthVault solutions conference a week later. I wasn’t totally successful at avoiding pre-written code, partly because I didn’t want to write UI code, and partly because there are a few parts of the HealthVault API that still need a little polishing, but overall, I was pleased with the result.

    This is the written version of that talk. My goal is to use the same progression that I did in the talk, and perhaps expand on a few topics that had to be limited due to time constraints.

    Installments will appear on my blog periodically, though those who ever read my C# column on MSDN may remember that I have an unconventional definition for “periodically”.

    Introduction to HealthVault Development #1: Introduction

  • Eric Gunnerson's Compendium

    Retro gaming at its best...


    Back when I was in high school, in the early 1980s, was when I was first introduced to computer games.  What we called "arcade games" at the time.

    There were three common systems for this.

    First of all, there was the TRS-80. You can read about all the exciting detail in the link, but the system could display text at 64 x 18, and graphics at a resolution of 128 x 48 if you used the special 2x3 grid characters. Each pixel was either black or an interesting blue/white (the phosphor used in the monitor was not pure white).

    In addition to not having any storage built in, it also had no sound output whatsoever. However, it was well-renowned for putting out tremendous amounts of RF interference, and somebody discovered that if you put an AM radio next to it, you could, through use of timing loops, generate interference that was somewhat related to what was going on in the game.

    But it was cheap. Not cheap enough for me to afford one, but cheap.

    The second system was the Apple II, sporting 280x192 high-resolution color graphics. Well, 'kindof-color' graphics - any pixel could be white or black, but only odd ones could be green or orange, and only even ones could be violet or blue.

    The sound system was a great improvement over the TRS-80, with a speaker that you could toggle to off or on. Not off or on with a tone, just off or on - any tone had to be done in software synthesis.

    Finally, the third system was the Atari 800 and 400. It was far more sophisticated - not only did it have the 6502 as the Apple II did, it had a separate graphics processor (named Antic) that worked its way through a display list, a television interface processor that implemented player-missile graphics (aka "sprites") and collision detection in hardware, and a third custom chip that handles the keyboard, 4-channel sound output, and controllers (we called them "paddles" and "joysticks" back then).

    It was light-years beyond the Apple in sophistication, which only shows you the importance of cheapness over elegance of design and implementation.

    Oh, and you could plug *cartridges* into it, so you didn't have to wait for your game to load from the cassette (or later, floppy disk) before you played it.

    My brother-in-law bought an Atari 400 (the younger sibling of the 800), and of course he had a copy of Star Raiders, arguably one of the first good first-person shooters.  He also had a copy of Miner 2049er, a 2-D walker/jumper that's a little bit like donkey kong and a bit like pac man.

    It was very addictive, and put 10 levels into a small cartridge.

    It was followed in 1984 by "Bounty Bob Strikes Back", featuring 30 levels.

    I played both a fair bit until we finally broke down and sold our Atari 800XL in the early 1990s.

    And now, Big Five software has released both games in emulator form, so you can run them on your PC.

    Marvel to the advanced graphics, and wonderful sound. Note that the gameplay and addiction is still there.

    I have to run it at 640x480 size or the keys aren't sensed correctly. Play Miner first, as the controls are slightly different, and you'll get confused.

    Highly recommended.

Page 3 of 46 (1,136 items) 12345»