<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Eric Gunnerson's C# Compendium</title><link>http://blogs.msdn.com/ericgu/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>21st Century Breakdown - show review</title><link>http://blogs.msdn.com/ericgu/archive/2009/07/04/21st-century-breakdown-show-review.aspx</link><pubDate>Sat, 04 Jul 2009 18:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9817664</guid><dc:creator>ericgu</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9817664.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9817664</wfw:commentRss><description>&lt;P&gt;Green Day remains&amp;nbsp;a very entertaining group to watch, and we had a great time.&lt;/P&gt;
&lt;P&gt;After a dinner at the traditional Seattle eatery 13 coins, we headed over the the Key for the show. Got there fairly early, and headed to the West side to buy some Merch (far less crowded than the east side), and the found our seats and waited.&lt;/P&gt;
&lt;P&gt;Opening group was "The Bravery". I cut opening bands a lot of slack because it's a hard crowd and the sound usually doesn't work well for you, but it wasn't to my taste. The vocals were muddy, and the songs sounded all the same to me. Happy they didn't play for very long.&lt;/P&gt;
&lt;P&gt;After a bunch of listening, 21st Century Breakdown hasn't caught on for me the way that American Idiot did, so I was hoping that they would play a lot of other stuff besides the new album. Which they did - opened with a few cuts of the new album, then a few off of idiot, then some old stuff (Dookie and newer, so not old old), some more new stuff, etc. Nice variety, and you can tell from the crowd reaction that they like the old stuff quite a&amp;nbsp;bit. &lt;/P&gt;
&lt;P&gt;Billie Joe played a lot less lead guitar than in the idiot show, concentrating more on vocals and rhythm guitar, especially on the new stuff. It seemed to work pretty well and the mix between his guitar and the backup guy was pretty good. &lt;/P&gt;
&lt;P&gt;A few issues since this was the first show. Crew isn't quite used to how things work yet (leading to a pretty funny 2-minute segment when the guitar tech keeps trying to hand Billie Joe his guitar and Billie Joe keeps singing), and a notably disappointing t-shirt gun, which despite several attempts couldn't launch the t-shirt more than about 30'. &lt;/P&gt;
&lt;P&gt;They played for just a bit over two hours, with only perhaps a 1 minute break before the encore. Billie Joe spends the whole two hours running around and singing, and it's pretty impressive.&lt;/P&gt;
&lt;P&gt;Great show.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Partial setlist:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Dookie:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Longview&lt;/LI&gt;
&lt;LI&gt;Basket Case&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Nimrod:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Hitchin' a ride&lt;/LI&gt;
&lt;LI&gt;King for a day&lt;/LI&gt;
&lt;LI&gt;Good riddance (time of your life) (closing song, acoustical)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Warning:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Minority&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;American idiot:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;American Idiot&lt;/LI&gt;
&lt;LI&gt;Jesus of suburbia&lt;/LI&gt;
&lt;LI&gt;Boulevard of broken dreams&lt;/LI&gt;
&lt;LI&gt;Holiday&lt;/LI&gt;
&lt;LI&gt;Are we the waiting&lt;/LI&gt;
&lt;LI&gt;St. Jimmy&lt;/LI&gt;
&lt;LI&gt;Homecoming&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;21st Century Breakdown:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Song of the Century&lt;/LI&gt;
&lt;LI&gt;21st Century breakdown&lt;/LI&gt;
&lt;LI&gt;Know your enemy&lt;/LI&gt;
&lt;LI&gt;Before the lobotomy&lt;/LI&gt;
&lt;LI&gt;21 guns&lt;/LI&gt;
&lt;LI&gt;(think I missed a couple here...)&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9817664" width="1" height="1"&gt;</description></item><item><title>Is programming a generic skill?</title><link>http://blogs.msdn.com/ericgu/archive/2009/06/25/is-programming-a-generic-skill.aspx</link><pubDate>Thu, 25 Jun 2009 16:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9803936</guid><dc:creator>ericgu</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9803936.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9803936</wfw:commentRss><description>&lt;P&gt;Came across a &lt;A class="" href="http://www.codethinked.com/post/2009/06/11/Is-Programming-A-Generic-Skill.aspx" mce_href="http://www.codethinked.com/post/2009/06/11/Is-Programming-A-Generic-Skill.aspx"&gt;post&lt;/A&gt; by Justin Etheredge discussion whether changing between languages is just a matter of syntax.&lt;/P&gt;
&lt;P&gt;Or, to pick a specific example, can a Java programmer quickly and easily learn to write C# code?&lt;/P&gt;
&lt;P&gt;The answer is obviously "yes". Development is about a way of thinking and approaching problems, and given the similarity between Java and C#, a good Java developer should take a minimal amount of time to learn how to write functional code in C#. The biggest barrier is libraries, which are more different than the languages are.&lt;/P&gt;
&lt;P&gt;The answer is equally as obviously "no". Sure, you can write functional code, but you will not be able to write idiomatic code. Like a high school senior with 4 years of French class on a trip to Paris, you can make yourself understood, but you aren't going to be mistaken as a native. You ask a question, somebody replies, "Ce ne sont pas vos oignons", and you just end thinking of soup.&lt;/P&gt;
&lt;P&gt;So, yeah, you can write C# code, but it's going to be Java written in C#. Given the closeness of the languages, it may be sufficient, but you're going to force some refactoring on&amp;nbsp;any idiomatic C# speakers who inherit your code.&lt;/P&gt;
&lt;P&gt;It can be worse - when I first started writing in Perl, I wrote C code in Perl, which just doesn't work very well. And over time, I became at least functional, though perhaps not idiomatic in Perl (though, because of TMTOWTDI, it's hard to judge that in Perl).&lt;/P&gt;
&lt;P&gt;However, if you can become idiomatic in multiple languages, your toolset broadens, and you become more useful in all your langauges. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9803936" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Livestrong Seattle Century report</title><link>http://blogs.msdn.com/ericgu/archive/2009/06/24/livestrong-seattle-century-report.aspx</link><pubDate>Wed, 24 Jun 2009 15:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9801662</guid><dc:creator>ericgu</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9801662.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9801662</wfw:commentRss><description>From my &lt;A class="" href="http://riderx.info/blogs/riderx/archive/2009/06/20/livestrong-seattle-century-2009.aspx" mce_href="http://riderx.info/blogs/riderx/archive/2009/06/20/livestrong-seattle-century-2009.aspx"&gt;cycling blog&lt;/A&gt;...&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9801662" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/Cycling/default.aspx">Cycling</category></item><item><title>Introduction to HealthVault Development #12: More than one person…</title><link>http://blogs.msdn.com/ericgu/archive/2009/06/19/introduction-to-healthvault-development-12-more-than-one-person.aspx</link><pubDate>Fri, 19 Jun 2009 22:41:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9792284</guid><dc:creator>ericgu</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9792284.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9792284</wfw:commentRss><description>&lt;p&gt;WeightTracker has gotten popular, and we have a new scenario. Our users would like us to extend our application so that they can easily enter weights for each member of the family.&lt;/p&gt;  &lt;p&gt;This will require us to delve a bit more deeply into users, records, and authentication, and we’ll also explore the HealthVault shell a bit more…&lt;/p&gt;  &lt;h2&gt;Accounts and records&lt;/h2&gt;  &lt;p&gt;HealthVault separates the concept of accounts and records. An account is associated with a specific set of credentials, and a record contains the health information for a specific person.&lt;/p&gt;  &lt;p&gt;It’s not uncommon for an account to have access to more than one record. A person might have access to their own record and the records of their children, spouse, or parents. &lt;/p&gt;  &lt;h2&gt;What data does your application use?&lt;/h2&gt;  &lt;p&gt;HealthVault supports two ways of dealing with records.&lt;/p&gt;  &lt;p&gt;A single-record application – which is what WeightTracker is right now – is intended to work with only one person’s data (ie one record) at a time. The platform keeps track of which record the application is using, and when writing code, you just need to use PersonInfo.SelectedRecord.&lt;/p&gt;  &lt;p&gt;A single-record application can switch between records by redirecting the user back to the HealthVault shell to choose the new record, and authorize it if necessary.&lt;/p&gt;  &lt;p&gt;The alternate way of dealing with applications is to work with multiple records simultaneously.&lt;/p&gt;  &lt;p&gt;We do this by adding the following entry to our web.config:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;add key=&amp;quot;WCPage_IsMRA&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And we also need to tell the shell that we’re an MRA application whenever we ask it to do something. We do this in AuthorizeEmotion.aspx.cs, and we’ll modify the code there to the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;string TargetQuery = &amp;quot;appid=cee3e0fc-03c6-40b4-9550-a151901b4a27&amp;amp;onopt1=Opt_Emotion&amp;amp;ismra=true&amp;quot;; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, we can go back to the &lt;a href="https://account.healthvault-ppe.com"&gt;HealthVault PPE shell&lt;/a&gt;, create a second record, make sure our existing record no longer allows WeightTracker to use it (via the “sharing” tab). And when we run WeightTracker, we’ll see the following:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/ericgu/images/9762862/original.aspx" /&gt; &lt;/p&gt;  &lt;p&gt;Note that there are now checkboxes next to the records. We select all of them, hit “continue”, and then we will need to authorize the application to access each record. &lt;/p&gt;  &lt;h2&gt;Displaying the list of authorized records&lt;/h2&gt;  &lt;p&gt;The list of records that the application is authorized is stored in PersonInfo.AuthorizedRecords. We’ll add a dropdown control to default.aspx:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Welcomes&amp;amp;nbsp;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:DropDownList ID=&amp;quot;c_dropDownCurrentRecord&amp;quot; runat=&amp;quot;server&amp;quot; Width=&amp;quot;262px&amp;quot; OnSelectedIndexChanged=&amp;quot;c_dropDownCurrentRecord_SelectedIndexChanged&amp;quot; AutoPostBack=&amp;quot;True&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and remove the references to c_labelUser from the code. &lt;/p&gt;  &lt;p&gt;We will use the drop-down list to display the current list of authorized records and to select the one that we want. We’ll add the following code, and call PopulateRecordDropDown() at the beginning of Page_Prerender(). &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;protected void c_dropDownCurrentRecord_SelectedIndexChanged(object sender, EventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (Guid recordId in PersonInfo.AuthorizedRecords.Keys)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (recordId.ToString() == c_dropDownCurrentRecord.SelectedValue)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PersonInfo.SelectedRecord = PersonInfo.AuthorizedRecords[recordId];       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;void PopulateRecordDropDown()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c_dropDownCurrentRecord.Items.Clear(); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; foreach (Guid recordId in PersonInfo.AuthorizedRecords.Keys)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HealthRecordInfo healthRecordInfo = PersonInfo.AuthorizedRecords[recordId]; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ListItem listItem = new ListItem(healthRecordInfo.Name, recordId.ToString()); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (recordId == PersonInfo.SelectedRecord.Id)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; listItem.Selected = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c_dropDownCurrentRecord.Items.Add(listItem);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We then need to update our height code to deal with cases where the height isn’t there (or perhaps you already did this…)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Height height = GetSingleValue&amp;lt;Height&amp;gt;(Height.TypeId);      &lt;br /&gt;if (height != null)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (height.Value.DisplayValue != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c_labelHeight.Text = height.Value.DisplayValue.ToString();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c_labelHeight.Text = height.Value.ToString();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;} &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;string bmiString = String.Empty;      &lt;br /&gt;if (height != null)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; double bmi = weight.Value.Kilograms / (height.Value.Meters * height.Value.Meters);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; bmiString = String.Format(&amp;quot;{0:F2}&amp;quot;, bmi);       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;After all of that, if you run the application, is should now allow you to select between the records. However, we still need to save the information about which record is current.&lt;/p&gt;  &lt;h2&gt;Saving the current record&lt;/h2&gt;  &lt;p&gt;To store the identifier of the current record, what we would like is a storage place that is associated with the person using the application rather than the a specific record. HealthVault provides that through the GetApplicationsSettings() and SetApplicationSettings() methods on the application connection. We could use those directly by putting some XML in there and then pulling it out, but we’re going to encapsulate that in a class. Here’s what we need to do:&lt;/p&gt;  &lt;p&gt;First, we’ll create a new class named “WeightTrackerApplicationSettings”. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;using System;      &lt;br /&gt;using System.Data;       &lt;br /&gt;using System.Configuration;       &lt;br /&gt;using System.Web;       &lt;br /&gt;using System.Web.Security;       &lt;br /&gt;using System.Web.UI;       &lt;br /&gt;using System.Web.UI.WebControls;       &lt;br /&gt;using System.Web.UI.WebControls.WebParts;       &lt;br /&gt;using System.Web.UI.HtmlControls;       &lt;br /&gt;using System.Xml;       &lt;br /&gt;using System.Xml.XPath;       &lt;br /&gt;using System.Text; &lt;/p&gt;    &lt;p&gt;using Microsoft.Health; &lt;/p&gt;    &lt;p&gt;public class WeightTrackerApplicationSettings      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private Guid _selectedRecordId; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public Guid SelectedRecordId      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return _selectedRecordId; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set { _selectedRecordId = value; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void LoadFromHealthVault(AuthenticatedConnection authenticatedConnection)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IXPathNavigable settingsNavigable = authenticatedConnection.GetApplicationSettings();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (settingsNavigable == null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator navigator = settingsNavigable.CreateNavigator(); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator appSettingsNode = navigator.SelectSingleNode(&amp;quot;app-settings&amp;quot;); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator selectedRecordNode = appSettingsNode.SelectSingleNode(&amp;quot;selected-record-id&amp;quot;); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string value = selectedRecordNode.Value;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _selectedRecordId = new Guid(value);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void SaveToHealthVault(AuthenticatedConnection authenticatedConnection)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XmlDocument document = new XmlDocument(); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XmlElement nodeWeightTrackerSettings = document.CreateElement(&amp;quot;app-settings&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; document.AppendChild(nodeWeightTrackerSettings); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XmlElement nodeSelectedRecordId = document.CreateElement(&amp;quot;selected-record-id&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeWeightTrackerSettings.AppendChild(nodeSelectedRecordId);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nodeSelectedRecordId.InnerText = _selectedRecordId.ToString(); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; authenticatedConnection.SetApplicationSettings(document);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then, we add the code to load in the settings at the beginning of Page_Prerender():&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;_weightTrackerApplicationSettings.LoadFromHealthVault(AuthenticatedConnection); &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and modify our methods:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;protected void c_dropDownCurrentRecord_SelectedIndexChanged(object sender, EventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (Guid recordId in PersonInfo.AuthorizedRecords.Keys)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (recordId.ToString() == c_dropDownCurrentRecord.SelectedValue)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PersonInfo.SelectedRecord = PersonInfo.AuthorizedRecords[recordId]; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _weightTrackerApplicationSettings.SelectedRecordId = recordId;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _weightTrackerApplicationSettings.SaveToHealthVault(AuthenticatedConnection);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;void PopulateRecordDropDown()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c_dropDownCurrentRecord.Items.Clear(); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; foreach (Guid recordId in PersonInfo.AuthorizedRecords.Keys)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HealthRecordInfo healthRecordInfo = PersonInfo.AuthorizedRecords[recordId]; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ListItem listItem = new ListItem(healthRecordInfo.Name, recordId.ToString()); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (recordId == PersonInfo.SelectedRecord.Id)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; listItem.Selected = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c_dropDownCurrentRecord.Items.Add(listItem);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;That stores the currently selected record away and then restores it when the page starts up.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Next Time&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Next time, we’ll display values from multiple records.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9792284" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category><category domain="http://blogs.msdn.com/ericgu/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>Rekeying the HealthVault/Amalga USB Key</title><link>http://blogs.msdn.com/ericgu/archive/2009/06/15/rekeying-the-healthvault-amalga-usb-key.aspx</link><pubDate>Mon, 15 Jun 2009 21:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9755933</guid><dc:creator>ericgu</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9755933.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9755933</wfw:commentRss><description>&lt;P&gt;If you attended the connected health conference last week, you got&amp;nbsp;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.&lt;/P&gt;
&lt;P&gt;But to get this protection, you'll need to change the combination to some other number. Here's how you do it:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Set the key to 0-0-0&lt;/LI&gt;
&lt;LI&gt;On the non-usb end, there's a small round button. Press it in with a pen.&lt;/LI&gt;
&lt;LI&gt;Change&amp;nbsp;the combination&lt;/LI&gt;
&lt;LI&gt;Press the button on the USB end back in.&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9755933" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category></item><item><title>Suggest a HealthVault topic...</title><link>http://blogs.msdn.com/ericgu/archive/2009/06/11/suggest-a-healthvault-topic.aspx</link><pubDate>Thu, 11 Jun 2009 19:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9727495</guid><dc:creator>ericgu</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9727495.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9727495</wfw:commentRss><description>&lt;P&gt;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. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9727495" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category></item><item><title>7 Hills of Kirkland 2009</title><link>http://blogs.msdn.com/ericgu/archive/2009/05/26/7-hills-of-kirkland-2009.aspx</link><pubDate>Wed, 27 May 2009 05:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9643548</guid><dc:creator>ericgu</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9643548.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9643548</wfw:commentRss><description>&lt;A class="" href="http://riderx.info/blogs/riderx/archive/2009/05/26/7-or-so-hills-of-kirkland-2009.aspx" mce_href="http://riderx.info/blogs/riderx/archive/2009/05/26/7-or-so-hills-of-kirkland-2009.aspx"&gt;7 Hills of Kirkland 2009&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9643548" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/Cycling/default.aspx">Cycling</category></item><item><title>21st Century Breakdown</title><link>http://blogs.msdn.com/ericgu/archive/2009/05/20/21st-century-breakdown.aspx</link><pubDate>Thu, 21 May 2009 02:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9633242</guid><dc:creator>ericgu</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9633242.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9633242</wfw:commentRss><description>&lt;P&gt;I picked up a copy of &lt;A class="" href="http://en.wikipedia.org/wiki/21st_Century_Breakdown" mce_href="http://en.wikipedia.org/wiki/21st_Century_Breakdown"&gt;Green Day's newest&lt;/A&gt; 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.&lt;/P&gt;
&lt;P&gt;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&amp;nbsp;&lt;A class="" href="http://en.wikipedia.org/wiki/Money_Money_2020" mce_href="http://en.wikipedia.org/wiki/Money_Money_2020"&gt;Money Money 2020&lt;/A&gt;&amp;nbsp;(a nice album if you like punk/new wave fusion), and one that's&amp;nbsp;a little bit country (and more than a little bit rock and rock).&lt;/P&gt;
&lt;P&gt;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&lt;/P&gt;
&lt;P&gt;&amp;nbsp;And yes, I'll be at Key arena with the wife and (now old enough for a Green Day concert) daughter on July 3rd.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9633242" width="1" height="1"&gt;</description></item><item><title>Microsoft Connected Health Conference</title><link>http://blogs.msdn.com/ericgu/archive/2009/05/05/microsoft-connected-health-conference.aspx</link><pubDate>Tue, 05 May 2009 17:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9589435</guid><dc:creator>ericgu</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9589435.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9589435</wfw:commentRss><description>&lt;P&gt;The HealthVault Partner Conference is a year older and has a new name.&lt;/P&gt;
&lt;P&gt;The &lt;A class="" href="https://www.msconnectedhealth.com/sitelogin.aspx" mce_href="https://www.msconnectedhealth.com/sitelogin.aspx"&gt;Microsoft Connected Health Conference&lt;/A&gt; will be held on June 10-12th at Meydenbauer Center in Bellevue, WA. &lt;/P&gt;
&lt;P&gt;If you enter the registration code on the page and choose "submit", you will get access to the details of the conference.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9589435" width="1" height="1"&gt;</description></item><item><title>Progressio per Patientia</title><link>http://blogs.msdn.com/ericgu/archive/2009/04/26/progressio-per-patientia.aspx</link><pubDate>Mon, 27 Apr 2009 03:36:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9570252</guid><dc:creator>ericgu</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9570252.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9570252</wfw:commentRss><description>&lt;p&gt;"Progress through suffering"&lt;/p&gt; &lt;p&gt;I have a friend (perhaps "riding acquaintance" is a more accurate term) named "&lt;a href="http://www.fatcyclist.com/"&gt;Elden Fat Cyclist&lt;/a&gt;". Actually, that's his stage name. His real name is "Harold Fat Cyclist".&lt;/p&gt; &lt;p&gt;Harold has been involved in &lt;a href="http://www.livestrong.com/"&gt;Livestrong&lt;/a&gt; for a while and - for reasons that will become obvious if you read his blog - this year has decided to organize "&lt;a href="http://www.fatcyclist.com/2008/11/12/lets-break-some-records/"&gt;Team Fat Cyclist&lt;/a&gt;", to try to win the team competition of the Livestrong challenge. &lt;/p&gt; &lt;p&gt;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 &lt;strong&gt;7900'&lt;/strong&gt; 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'.&lt;/p&gt; &lt;p&gt;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. &lt;/p&gt; &lt;p&gt;That's where you come in. &lt;/p&gt; &lt;p&gt;The event is a fundraiser for cancer research, and I'm looking for people to sponsor me in this undertaking.&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;If you can spare some money to help out a worthy cause (cancer research, not me suffering), please head on over to &lt;a href="https://www.kintera.org/faf/donorReg/donorPledge.asp?ievent=294734&amp;amp;supid=254199935"&gt;my fundraising page&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9570252" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/Cycling/default.aspx">Cycling</category></item><item><title>Introduction to HealthvaultDevelopment #11: Data filtering</title><link>http://blogs.msdn.com/ericgu/archive/2009/04/17/introduction-to-healthvaultdevelopment-11-data-filtering.aspx</link><pubDate>Fri, 17 Apr 2009 22:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9554673</guid><dc:creator>ericgu</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9554673.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9554673</wfw:commentRss><description>&lt;P&gt;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.&lt;/P&gt;
&lt;P&gt;That will take us into filtering…&lt;/P&gt;
&lt;P&gt;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.&lt;/P&gt;
&lt;H1&gt;Common Data Filtering&lt;/H1&gt;
&lt;P&gt;There are some properties that are shared across all data types. This section discusses filtering on those items. &lt;/P&gt;
&lt;H2&gt;Filtering based on the number of items&lt;/H2&gt;
&lt;P&gt;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:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;asp:CheckBox ID="c_CheckboxLast5Items" runat="server" Text="Last 5 items only" AutoPostBack="True" /&amp;gt;&amp;lt;br /&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;and then we change the filter definition in default.aspx.cs to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;filter.View.Sections |= HealthRecordItemSections.Audits; &lt;BR&gt;if (c_CheckboxLast5Items.Checked) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; filter.MaxItemsReturned = 5; &lt;BR&gt;} &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you run this, when you click the checkbox you will only see the last 5 weight measurements. &lt;/P&gt;
&lt;P&gt;&amp;lt;aside&amp;gt;&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;This is transparent to the calling application, and the default value is usually fine.&amp;nbsp; 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. &lt;/P&gt;
&lt;P&gt;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.&lt;/P&gt;
&lt;P&gt;&amp;lt;/aside&amp;gt;&lt;/P&gt;
&lt;H2&gt;Filtering based on dates&lt;/H2&gt;
&lt;P&gt;We can also filter based on the&amp;nbsp; &lt;/P&gt;
&lt;P&gt;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:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;asp:CheckBox ID="c_CheckboxLast3MonthsOnly" runat="server" Text="Last 3 months only" AutoPostBack="True" /&amp;gt;&amp;lt;br /&amp;gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;and the following is added to the filter definition:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;if (c_CheckboxLast3MonthsOnly.Checked) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; filter.UpdatedDateMin = DateTime.Now - new TimeSpan(30, 0, 0, 0); &lt;BR&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Filtering based on application id&lt;/H2&gt;
&lt;P&gt;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).&lt;/P&gt;
&lt;P&gt;This is done with the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;filter.UpdatedApplication = ApplicationConnection.ApplicationId;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Adding the checkbox and the appropriate logic is left as an exercise to the reader. &lt;/P&gt;
&lt;H1&gt;Type-Specific Filtering&lt;/H1&gt;
&lt;P&gt;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.&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;To make this easier, I wrote the &lt;A href="http://blogs.msdn.com/ericgu/archive/2009/04/10/healthvault-xpath-explorer.aspx" mce_href="http://blogs.msdn.com/ericgu/archive/2009/04/10/healthvault-xpath-explorer.aspx"&gt;HealthVault XPath Explorer&lt;/A&gt;. 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. &lt;/P&gt;
&lt;P&gt;For our application, if we want to only return items where the weight value is less than 50 kilograms, we can use the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;filter.XPath = "/thing/data-xml/weight/value/kg[.&amp;gt; 50]";&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In the “[. &amp;gt; 50]”, the “.” refers to the current node, so it means “kg &amp;gt; 50”. &lt;/P&gt;
&lt;H1&gt;Automatic user sign in&lt;/H1&gt;
&lt;P&gt;You may have noticed that our demo app requires us to sign in every time we run it. This behavior is configurable:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Go to the application configuration center&lt;/LI&gt;
&lt;LI&gt;Select the demo application&lt;/LI&gt;
&lt;LI&gt;Go to the “Misc” tab&lt;/LI&gt;
&lt;LI&gt;Toggle the “automatic user sign-in” radio button to “yes”&lt;/LI&gt;
&lt;LI&gt;Set a sign-in duration in seconds (I chose 3600).&lt;/LI&gt;
&lt;LI&gt;Click “Make changes”.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;H1&gt;Next Time&lt;/H1&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericgu/archive/2009/06/19/introduction-to-healthvault-development-12-more-than-one-person.aspx" mce_href="http://blogs.msdn.com/ericgu/archive/2009/06/19/introduction-to-healthvault-development-12-more-than-one-person.aspx"&gt;Next time&lt;/A&gt; we'll modify our application to work for the whole family. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9554673" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category><category domain="http://blogs.msdn.com/ericgu/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>HealthVault XPath Explorer</title><link>http://blogs.msdn.com/ericgu/archive/2009/04/10/healthvault-xpath-explorer.aspx</link><pubDate>Fri, 10 Apr 2009 23:48:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9544289</guid><dc:creator>ericgu</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9544289.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9544289</wfw:commentRss><description>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;You can find the code &lt;a href="http://code.msdn.microsoft.com/HVXPathExplorer"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Make a copy of the HelloWorld sample, put the two files into it, and run the sample. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9544289" width="1" height="1"&gt;</description></item><item><title>Introduction to HealthVault Development #10: Adding additional data to healthvault</title><link>http://blogs.msdn.com/ericgu/archive/2009/03/13/introduction-to-healthvault-development-10-adding-additional-data-to-healthvault.aspx</link><pubDate>Sat, 14 Mar 2009 00:12:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9473931</guid><dc:creator>ericgu</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9473931.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9473931</wfw:commentRss><description>&lt;p&gt;We have a new user request. One of our users would like to store how hungry he whenever he enters a weight value.&lt;/p&gt;  &lt;p&gt;We head off to the &lt;a href="http://msdn.microsoft.com/en-us/healthvault/default.aspx"&gt;HealthVault MSDN page&lt;/a&gt;, go to the &lt;a href="http://msdn.microsoft.com/en-us/healthvault/bb663039.aspx"&gt;learn page&lt;/a&gt; and then the &lt;a href="http://msdn.microsoft.com/en-us/healthvault/cc451929.aspx"&gt;reference page&lt;/a&gt;, and then choose &lt;a href="http://developer.healthvault.com/types/types.aspx"&gt;HealthRecordItem Type Schema Browser&lt;/a&gt;. This page talks to the developer platform to find out what types are currently supported by the platform. &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;Or, we could explore other ways to add the hunger data to HealthVault.&lt;/p&gt;  &lt;p&gt;The first way is to ask the HealthVault team to &lt;a href="http://msdn.microsoft.com/en-us/healthvault/bb892883.aspx"&gt;add a new data type&lt;/a&gt;. 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. &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;While you wait for us – or if the information is not of general interest – there are three ways to add information:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;All data types provide the CommonData.Note and CommonData.Tags properties for your use.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;All data types support adding extension data in XML format.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;A custom application-specific data type can be created. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;h3&gt;Extensions&lt;/h3&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;The XML for the extension is in the following format:&lt;/p&gt;  &lt;p&gt;&amp;lt;extension&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;extension-name&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; xml data goes here     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/extension-name&amp;gt;     &lt;br /&gt;&amp;lt;/extension&amp;gt;&lt;/p&gt;  &lt;p&gt;The meaning of the XML data inside is purely up to the application. &lt;/p&gt;  &lt;p&gt;For hunger, we’ll use an entry like this:&lt;/p&gt;  &lt;p&gt;&amp;lt;extension&amp;gt;&amp;lt;hunger&amp;gt;Moderate&amp;lt;/hunger&amp;gt;&amp;lt;/extension&amp;gt;&lt;/p&gt;  &lt;h4&gt;Adding the extension to our project&lt;/h4&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;void AddHungerToWeight(Weight weight)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; HealthRecordItemExtension extension = new HealthRecordItemExtension(ExtensionWeightTrackerHunger);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; XPathNavigator navigator = extension.ExtensionData.CreateNavigator();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; string innerXml = @&amp;quot;&amp;lt;extension&amp;gt;&amp;lt;hunger&amp;gt;&amp;quot; + c_dropDownListHunger.SelectedItem.Value +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @&amp;quot;&amp;lt;/hunger&amp;gt;&amp;lt;/extension&amp;gt;&amp;quot;;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; navigator.InnerXml = innerXml; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; weight.CommonData.Extensions.Add(extension);      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That helper is already in the project, so you can just add the call right before the weight value is saved:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;AddHungerToWeight(weight);      &lt;br /&gt;PersonInfo.SelectedRecord.NewItem(weight);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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 “&amp;lt;application&amp;gt;.&amp;lt;extension-name&amp;gt;” format. The constant that is currently in the project is incorrect – change it to “WeightTracker.Hunger”.&lt;/p&gt;  &lt;p&gt;In addition to the actual data stored in the extension (the ExtensionData property), there are a few other items that you can store:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Logo&lt;/strong&gt; is the url of a logo to display with the extension.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt; is the source identifier.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Transform&lt;/strong&gt; is the URL of a transform that converts the extension data into an HTML form.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Version&lt;/strong&gt; is the version number of the extension &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We’ll follow our usual pattern in modifying our fetching code:&lt;/p&gt;  &lt;p&gt;First, add a “Hunger” header as the second-to-last entry. &lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;string hunger = String.Empty;      &lt;br /&gt;foreach (HealthRecordItemExtension extension in weight.CommonData.Extensions)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (extension.Source == ExtensionWeightTrackerHunger)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator navigator = extension.ExtensionData.CreateNavigator();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator value = navigator.SelectSingleNode(&amp;quot;extension/hunger&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (value != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; hunger = value.Value;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;} &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Finally, add hunger to the call to AddCellsToTable(). Run the project and verify that it works. &lt;/p&gt;  &lt;h3&gt;A Nicer Approach&lt;/h3&gt;  &lt;p&gt;We can make things better by using a derived class for the extension. &lt;/p&gt;  &lt;p&gt;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”. &lt;/p&gt;  &lt;p&gt;Replace the class with the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;using System;      &lt;br /&gt;using System.Xml;       &lt;br /&gt;using System.Xml.XPath;       &lt;br /&gt;using Microsoft.Health;       &lt;br /&gt;using Microsoft.Health.ItemTypes; &lt;/p&gt;    &lt;p&gt;public class HungerExtension : HealthRecordItemExtension      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; static readonly string ExtensionSource = &amp;quot;WeightTracker.Hunger&amp;quot; ; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; string m_hunger; &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public HungerExtension()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public HungerExtension(string hunger)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : base(ExtensionSource)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; m_hunger = hunger;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Source = ExtensionSource;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public string Hunger      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return m_hunger; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set { m_hunger = value; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; protected override void ParseXml(IXPathNavigable extensionData)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator navigator = extensionData.CreateNavigator();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; XPathNavigator hungerNode = navigator.SelectSingleNode(&amp;quot;extension/Hunger&amp;quot; ); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (hungerNode != null)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; m_hunger = hungerNode.Value;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; protected override void WriteXml(System.Xml.XmlWriter writer)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteStartElement(&amp;quot;Hunger&amp;quot;);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteString(m_hunger);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteEndElement();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public static void RegisterExtensionHandler()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ItemTypeManager.RegisterExtensionHandler(ExtensionSource, typeof(HungerExtension), true);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;Now that we have the class, it’s much easier to use our extension.&lt;/p&gt;  &lt;p&gt;First, add the call to register the extension before the weight values are loaded:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;HungerExtension.RegisterExtensionHandler(); &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Modify the code to fetch the hunger value to the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;string hunger = String.Empty;      &lt;br /&gt;foreach (HealthRecordItemExtension extension in weight.CommonData.Extensions)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; HungerExtension hungerExtension = extension as HungerExtension;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (hungerExtension != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; hunger = hungerExtension.Hunger;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Change the code to save the hunger to the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;weight.CommonData.Extensions.Add(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new HungerExtension(c_dropDownListHunger.SelectedItem.Value));       &lt;br /&gt;PersonInfo.SelectedRecord.NewItem(weight);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Run the application, and verify that it works. Then delete the unnecessary helper methods and string constant from default.aspx.cs&lt;/p&gt;  &lt;h4&gt;Other resources:&lt;/h4&gt;  &lt;p&gt;There is &lt;a href="http://developer.healthvault.com/sdk/docs/index.html"&gt;another set of pages&lt;/a&gt; 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. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;Next Time&lt;/h3&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Next time, we’ll talk about &lt;a href="http://blogs.msdn.com/ericgu/archive/2009/04/17/introduction-to-healthvaultdevelopment-11-data-filtering.aspx"&gt;data filtering&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9473931" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category><category domain="http://blogs.msdn.com/ericgu/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>After SchooL chocLate cookies</title><link>http://blogs.msdn.com/ericgu/archive/2009/03/08/after-school-choclate-cookies.aspx</link><pubDate>Mon, 09 Mar 2009 04:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9467292</guid><dc:creator>ericgu</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9467292.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9467292</wfw:commentRss><description>&lt;UL&gt;
&lt;LI&gt;2 cups chocLate Syrip&lt;/LI&gt;
&lt;LI&gt;2 cups flour&lt;/LI&gt;
&lt;LI&gt;1/4 cup maLLases&lt;/LI&gt;
&lt;LI&gt;5 cups oatmeaL&lt;/LI&gt;
&lt;LI&gt;5 TabLespoons SaLt&lt;/LI&gt;
&lt;LI&gt;5 teaspoons BakingSoda&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Put OatmeaL, SaLt, fLour and Soda in bowl&lt;/P&gt;
&lt;P&gt;Stir in syrip and MaLLases&lt;/P&gt;
&lt;P&gt;Bake ten minits&lt;/P&gt;
&lt;P&gt;Temp 345&lt;/P&gt;
&lt;P&gt;Eric, age 7&lt;/P&gt;
&lt;P&gt;(I was cleaning out some old stuff this weekend, and thought I would share it with you)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9467292" width="1" height="1"&gt;</description></item><item><title>Introduction to HealthVault Development #9: Optional Authorization</title><link>http://blogs.msdn.com/ericgu/archive/2009/03/06/introduction-to-healthvault-development-9-optional-authorization.aspx</link><pubDate>Fri, 06 Mar 2009 21:54:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9463504</guid><dc:creator>ericgu</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericgu/comments/9463504.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericgu/commentrss.aspx?PostID=9463504</wfw:commentRss><description>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;What to do? What to do?&lt;/p&gt;  &lt;h3&gt;Enter optional auth&lt;/h3&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;h4&gt;Setting up our optional authorization rule&lt;/h4&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;h4&gt;Determining type permissions&lt;/h4&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;We can ask the platform for information about our access to the Emotion data type with the following code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;List&amp;lt;Guid&amp;gt; items = new List&amp;lt;Guid&amp;gt;();      &lt;br /&gt;items.Add(Emotion.TypeId);       &lt;br /&gt;Collection&amp;lt;HealthRecordItemTypePermission&amp;gt; permissions =       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PersonInfo.SelectedRecord.QueryPermissions(items); &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This code asks the selected record whether it has access to Emotion. If there is no access, the permissions collection will be empty.&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;HealthRecordItemTypePermission emotionPermission =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetItemPermission(Emotion.TypeId); &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;if (emotionPermission.OnlineAccessPermissions == HealthRecordItemPermissions.None)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c_linkEnableMoodTracking.Visible = true;       &lt;br /&gt;}       &lt;br /&gt;else       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c_labelMood.Visible = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c_dropDownListMood.Visible = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PopulateDropDownFromEnum(c_dropDownListMood, typeof(Mood));       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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).&lt;/p&gt;  &lt;p&gt;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”.&lt;/p&gt;  &lt;h3&gt;Asking the user for access&lt;/h3&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;Here’s the code that will do the redirect:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;string TargetQuery =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;appid=f36debe2-c2a3-434a-b822-f8c294fdecf9&amp;amp;onopt1=Opt_Emotion&amp;quot;;       &lt;br /&gt;RedirectToShellUrl(&amp;quot;APPAUTH&amp;quot;, TargetQuery); &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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 &lt;a href="http://msdn.microsoft.com/en-us/healthvault/cc265056.aspx"&gt;HealthVault Shell Redirect Interfaces&lt;/a&gt; page. &lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;h3&gt;Storing and displaying Mood values…&lt;/h3&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Emotion emotion = null;      &lt;br /&gt;if (c_labelMood.Visible)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; emotion = new Emotion(new HealthServiceDateTime(DateTime.Now));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; emotion.Mood = (Mood) Int32.Parse(c_dropDownListMood.SelectedItem.Value);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PersonInfo.SelectedRecord.NewItem(emotion);       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and then modify the code that sets up the relationship:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;weight.CommonData.RelatedItems.Add(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new HealthRecordItemRelationship(exercise.Key));       &lt;br /&gt;if (emotion != null)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; weight.CommonData.RelatedItems.Add(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new HealthRecordItemRelationship(emotion.Key));       &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;PersonInfo.SelectedRecord.NewItem(weight); &lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Displaying mood values in the table&lt;/h4&gt;  &lt;p&gt;The header on the table needs to change based on whether we are tracking mood or not:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;if (c_labelMood.Visible)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AddHeaderCells(c_tableWeight, &amp;quot;Date&amp;quot;, &amp;quot;Weight&amp;quot;, &amp;quot;BMI&amp;quot;, &amp;quot;App Name&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Minutes&amp;quot;, &amp;quot;Mood&amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;quot;);       &lt;br /&gt;}       &lt;br /&gt;else       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AddHeaderCells(c_tableWeight, &amp;quot;Date&amp;quot;, &amp;quot;Weight&amp;quot;, &amp;quot;BMI&amp;quot;, &amp;quot;App Name&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Minutes&amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;quot;);       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We add the following to our relationship-fetching code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Emotion emotion = relatedItem as Emotion;      &lt;br /&gt;if (emotion != null)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mood = emotion.Mood.ToString();       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;after declaring “string mood” right below “string minutes”.&lt;/p&gt;  &lt;p&gt;And finally, we modify our code that adds the data to the table:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;if (c_labelMood.Visible)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AddCellsToTable(c_tableWeight, weight.When.ToString(),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; weight.Value.DisplayValue.ToString(), bmiString, appName, minutes, mood);       &lt;br /&gt;}       &lt;br /&gt;else       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AddCellsToTable(c_tableWeight, weight.When.ToString(),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; weight.Value.DisplayValue.ToString(), bmiString, appName, minutes);       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With that code, the application should now support entering and displaying mood information.&lt;/p&gt;  &lt;h4&gt;De-authorization&lt;/h4&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;h3&gt;Current Code&lt;/h3&gt;  &lt;p&gt;To help keep your code in sync with mine, I’ve uploaded my current code to &lt;a href="http://code.msdn.microsoft.com/HVWeightTracker9"&gt;MSDN Code Gallery&lt;/a&gt;. You will need to change my source so that it uses your application ID rather than mine.&lt;/p&gt;  &lt;h3&gt;Suggestions&lt;/h3&gt;  &lt;p&gt;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, &lt;a href="mailto:ericgu@microsoft.com"&gt;let me know&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Next Time&lt;/h3&gt;  &lt;p&gt;Next time, we’ll be looking at &lt;a href="http://blogs.msdn.com/ericgu/archive/2009/03/13/introduction-to-healthvault-development-10-adding-additional-data-to-healthvault.aspx"&gt;how to store hunger information&lt;/a&gt; in our application.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9463504" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericgu/archive/tags/HealthVault/default.aspx">HealthVault</category><category domain="http://blogs.msdn.com/ericgu/archive/tags/Tutorial/default.aspx">Tutorial</category></item></channel></rss>