January, 2009

Posts
  • Eric Gunnerson's Compendium

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

    • 2 Comments

     

    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.

    <aside>

    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.

    </aside>

    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);
        searcher.Filters.Add(filter);

        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

    • 0 Comments

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

    OEDILF

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #4 – Storing and retrieving weights

    • 3 Comments

    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:

    PersonInfo.SelectedRecord.NewItem(weight);

    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.

    <aside>

    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.

    </aside>

    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);
    searcher.Filters.Add(filter);

     

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

     

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

     

    <aside>

    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.

    </aside>

    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(), 
                                 weight.Value.DisplayValue.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…

    #5

  • Eric Gunnerson's Compendium

    New computer

    • 5 Comments

    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

    • 3 Comments

    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.

    #4

  • Eric Gunnerson's Compendium

    Introduction to HealthVault Development #2: Hello World

    • 1 Comments

    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 http://www.healthvault-ppe.com. 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 http://www.healthvault.com.

    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 asp.net 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:

    <system.net>
        <
    defaultProxy enabled="true" useDefaultCredentials="true">
            <
    proxy usesystemdefault="True"/>
        </defaultProxy>
    </
    system.net>

    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

    • 2 Comments

    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

    • 2 Comments

    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

Page 1 of 1 (8 items)