<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>davidpoll.com &#187; WCF RIA Services</title>
	<atom:link href="http://www.davidpoll.com/tag/wcf-ria-services/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidpoll.com</link>
	<description>Software development and other goofy geeky goodness.</description>
	<lastBuildDate>Sat, 18 Jun 2011 22:03:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Common Navigation UI and Authorization-driven Sitemaps</title>
		<link>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/</link>
		<comments>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/#comments</comments>
		<pubDate>Mon, 10 May 2010 22:00:36 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Controls]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[Sitemap]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/</guid>
		<description><![CDATA[Navigation-driven Silverlight applications tend to share some common pieces of UI.&#160; Traditionally, this has required sprinkling HyperlinkButtons throughout the application’s XAML.&#160; For ASP.NET a number of controls intended to drive navigation exist.&#160; These controls are driven by a sitemap, integrate well with authorization and roles (through sitemap trimming), and provide common user experiences around hierarchical [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Navigation-driven Silverlight applications tend to share some common pieces of UI.&#160; Traditionally, this has required sprinkling HyperlinkButtons throughout the application’s XAML.&#160; For ASP.NET a <a href="http://msdn.microsoft.com/en-us/library/e468hxky.aspx#SiteNavigationControls" target="_blank">number of controls intended to drive navigation exist</a>.&#160; These controls are driven by a sitemap, integrate well with authorization and roles (through sitemap trimming), and provide common user experiences around hierarchical application structures such as a TreeView-based list of hyperlinks and Breadcrumbs or navigation paths.&#160; These controls provide the user with context as to where in the application/site they currently are as well as where within the application they can go.</p>
<p>In this post, I’ll introduce a few controls that attempt to mimic this behavior in a Navigation-driven Silverlight application.&#160; I have added these controls to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a>, and you’re welcome to use and modify them – or use them as examples for your own development – as you see fit.&#160; The controls are:</p>
<ul>
<li>TreeViewNavigator – a control which represents a sitemap as a TreeView </li>
</ul>
<p align="center"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A TreeView Sitemap." border="0" alt="A TreeView Sitemap." src="http://www.davidpoll.com/wp-content/uploads/2010/05/image.png" width="316" height="516" /> </p>
<ul>
<li>BreadCrumbNavigator – a control which represents your current location within the sitemap’s link hierarchy and allows navigation back up the hierarchy as well as to siblings of any node within the hierarchy </li>
</ul>
<p align="center"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A BreadCrumb sitemap." border="0" alt="A BreadCrumb sitemap." src="http://www.davidpoll.com/wp-content/uploads/2010/05/image1.png" width="453" height="30" /> </p>
<p>If you’ve been following the evolution of my sample projects, you may have noticed some navigation UI that’s not built into the default navigation application template and has controls that look like the ones I’ve described above.&#160; Surprise, surprise! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; You can see this in action <a href="http://www.davidpoll.com/Samples/SLaB/" target="_blank">here</a>.</p>
<h3>How does this type of UI work?</h3>
<p>At its core, these controls have the same common set of functionality:</p>
<ul>
<li>Rendering UI based on a sitemap </li>
<li>Keeping UI synchronized with the current page within the application </li>
<li>Trimming the sitemap based upon the roles the current user belongs to and the metadata in the sitemap </li>
</ul>
<p>The goal of these controls is to allow the navigation structure of an application to be exposed to a user in a declarative fashion, much as one can do using <a href="http://msdn.microsoft.com/en-us/library/yy2ykkab.aspx" target="_blank">ASP.NET sitemaps</a>.&#160; The API for the controls above uses Sitemaps that can be specified in XAML, but follow the same general structure as in ASP.NET.</p>
<p>For example, the sitemaps displayed above are produced by the following XAML:</p>
<pre class="code">    <span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Sitemap&quot;
                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;
                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;My homepage.  Check it out and see what it's all about!&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home&quot;
                          </span><span style="color: red">Description</span><span style="color: blue">=&quot;The home page.&quot;
                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Features&quot;
                          </span><span style="color: red">Description</span><span style="color: blue">=&quot;Demonstrations of Silverlight and Beyond features.&quot;&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Navigation&quot;&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Local Pages&quot;&gt;
<strong><em>                    &lt;</em></strong></span><strong><em><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span></em></strong><strong><em><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span></em></strong><strong><em><span style="color: blue">=&quot;About&quot;
                                      </span><span style="color: red">Description</span></em></strong><strong><em><span style="color: blue">=&quot;The about page.&quot;
                                      </span><span style="color: red">Roles</span></em></strong><strong><em><span style="color: blue">=&quot;Foo&quot;
                                      </span><span style="color: red">Uri</span></em></strong><span style="color: blue"><strong><em>=&quot;/Views/About.xaml&quot; /&gt;</em></strong>
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;A broken link&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/NonExistent.xaml&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;On-Demand Xaps&quot;
                                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages in Xaps that will be loaded on-demand.&quot;
                                  </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/SitemapPage.xaml?sitemapname=OnDemandSitemap&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;This Domain&quot;&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page in a big xap&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,SecondaryXap.xap/SecondaryXap;component/Page1.xaml&quot; /&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Awesome Page&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,TernaryXap.xap/TernaryXap;component/AwesomePage.xaml&quot; /&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Penguins (mapped Uri + metadata)&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/remote/TernaryXap/AwesomePage.xaml?Site=http://www.davidpoll.com&amp;amp;First Name=David&amp;amp;Last Name=Poll&amp;amp;Title=Penguins!&amp;amp;Please rate...&quot; /&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Cross-Domain&quot;&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;http://open.depoll.com Page&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://http:,,open.depoll.com,SimpleApplication,SimpleApplication.xap/SimpleApplication;component/Depoll.xaml?Source=http://open.depoll.com&amp;amp;File=wildlife.wmv&quot; /&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Printing&quot;
                                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages that demonstrate printing utilities that simplify pagination of data and printing of complex data sets.&quot;
                                  </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/SitemapPage.xaml?sitemapname=PrintingSitemap&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Collection Printing (DataGrid)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/PrintingPage.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Collection Printing (Template-based)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/ItemTemplatePrinting.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Pre-defined page printing (Template-based)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/PredefinedPages.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Useful XAML Tools&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;Demo (simple QueryString)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/ObservableDictionaryDemo.xaml?a=b&amp;amp;c=d&amp;amp;e=f&amp;amp;g=h&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;Demo (more complex QueryString)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/ObservableDictionaryDemo.xaml?a=b&amp;amp;Name=David Eitan Poll&amp;amp;Url=http://www.davidpoll.com&amp;amp;No Value&amp;amp;Order=Dictionary&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home Page&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;Navigation Posts&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/tag/navigation/&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Posts&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/tag/silverlight-and-beyond-slab/&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Download Page&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/downloads-and-samples/#SLaB&quot; /&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>You’ll note that the “About” link in the Sitemap above (bold/italic above) is missing from the TreeView.&#160; This is because the sitemaps do principal-based trimming of the sitemaps, ensuring that users only see the links they’re authorized to see.&#160; </p>
<p>In addition, the controls above stay in sync with the current page the user is viewing.</p>
<p>To get all of this functionality, there are three primary properties to set on the navigation controls (which derive from the Navigator abstract base class for this common functionality):</p>
<ul>
<li>Sitemap – usually, this is set to a Sitemap that is defined in resources somewhere, and may be shared across multiple navigation controls. </li>
<li>CurrentSource – if the navigation control needs to stay in sync with the user’s current location (which is not always the case – e.g. on Error/404-ish pages), bind it to the CurrentSource of the Frame that it will be navigating </li>
<li>Principal – if the navigation control should trim the sitemap based upon the User’s authorization, bind the Principal to be that of the current user.&#160; In the case of RIA Services, this can be done through the WebContext </li>
</ul>
<p>Ultimately, using these controls just requires some simple XAML.&#160; For the TreeViewNavigator:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">TreeViewNavigator </span><span style="color: red">CurrentSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame, </span><span style="color: red">Path</span><span style="color: blue">=CurrentSource}&quot;
                        </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;
                        </span><span style="color: red">Sitemap</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">Sitemap</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p>And for the BreadCrumbNavigator:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">BreadCrumbNavigator </span><span style="color: red">CurrentSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">CurrentSource</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame}&quot;
                          </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;
                          </span><span style="color: red">Sitemap</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">Sitemap</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h3>What can I customize?</h3>
<p>These controls are made to work with any ISitemap, which is, at its core, a container for a collection of ISitemapNodes.&#160; You can provide custom implementations of these, customizing your sitemaps to your heart’s content!&#160; For example, you might make sitemaps and sitemap nodes which:</p>
<ul>
<li>Retrieve their data from an ASP.NET xml-based sitemap file </li>
<li>Authorize users for access to nodes based upon more than just roles </li>
<li>Check authorization based on metadata on the page type itself, or by using a NavigationAuthorizer from the AuthContentLoader library </li>
<li>Import one sitemap into another (I’ve actually provided an implementation of this in SLaB so that sitemaps and sub-sitemaps can be used) </li>
</ul>
<p>Furthermore, the controls themselves are look-less, and you should be able to completely re-template them, customizing how hyperlinks are displayed, how much of the tree is expanded, and so on.&#160; If there’s something I’m missing, let me know!</p>
<h3>So, can I see it in action?</h3>
<p>Of course!&#160; You know I never leave you without a demo!&#160; In fact, today I’ve got two for you!</p>
<p>First, the <a href="http://www.davidpoll.com/Samples/SLaB/" target="_blank">SLaB demo application</a> itself uses these controls.&#160; Click around and see how things behave.&#160; You’ll notice the controls are the centerpiece of the navigation UI, but also make appearances throughout the application, <a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=PrintingSitemap" target="_blank">such as on “category pages”</a> that list only the links within a particular section of the site, and on <a href="http://www.davidpoll.com/Samples/SLaB/#/Views/NonExistent.xaml" target="_blank">error pages</a> within the application, making it easier for users to get back to useful locations within the application.</p>
<p>The second demo application is meant to show role-driven sitemap trimming.&#160; It uses <a href="http://www.silverlight.net/getstarted/riaservices/" target="_blank">WCF RIA Services</a> to drive authentication and authorization, and shows and hides parts of the sitemap based upon the roles the user belongs to.&#160; You can log in using the following credentials:</p>
<p><strong>User</strong>: Test</p>
<p><strong>Password</strong>: _Testing</p>
<p>Experiment with the application and what happens to the navigation controls as you log in and log out.&#160; This also uses the AuthContentLoader from SLaB to perform additional authorization before actually loading any page.</p>
<p><a href="http://www.davidpoll.com/Samples/SitemapBusinessApplication/ScratchBusinessApplicationTestPage.html#/Views/Home.xaml" target="_blank"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Authorization-driven navigation controls" border="0" alt="Authorization-driven navigation controls" src="http://www.davidpoll.com/wp-content/uploads/2010/05/image2.png" width="644" height="432" /></a>&#160;</p>
<p>The XAML for the sitemap in the application above shows how access can be restricted and how trimming takes effect:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Sitemap&quot;
                </span><span style="color: red">Title</span><span style="color: blue">=&quot;Scratch Business Application&quot;
                </span><span style="color: red">Description</span><span style="color: blue">=&quot;A sample RIA Services Business application that uses SLaB to represent its navigation and do authorization.&quot;&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;The home page for the application&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Broken Link&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;A broken link&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/NonExistentPage.xaml&quot; /&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Non-Trimmed)&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Trimmed)&quot;
                        </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml?trimmed&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml?trimmed&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Leaf nodes trimmed)&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml?leaftrimmed&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml?leaftrimmed&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;David Poll's homepage&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com&quot;
                        </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot; /&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap</span><span style="color: blue">&gt;
</span></pre>
<h3>Cool… but where are the bits?</h3>
<p>Well, the good news is that you can get all of these controls in my Silverlight and Beyond (SLaB) libraries!&#160; Give them a shot and let me know what you think.&#160; What’s missing from these controls?&#160; What other pieces of user experience are you looking for?&#160; Are the behaviors of the TreeViewNavigator and BreadCrumbNavigator correct for your scenarios and desired UX?</p>
<p>With that said, here’s a summary of the links and access to the source!</p>
<li><a href="http://www.davidpoll.com/Samples/SLaB/">Live Sample</a> (<a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.5.zip">source &#8212; found in the SLaB v0.7 source under &quot;ScratchApplication&quot;</a>) </li>
<li><a href="http://www.davidpoll.com/Samples/SitemapBusinessApplication/ScratchBusinessApplicationTestPage.html" target="_blank">Live Sample using RIA Services for AuthN/AuthX</a> (<a href="http://www.davidpoll.com/Samples/Download/SitemapBusinessApplication.zip" target="_blank">source</a>)&#160;
<p><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.7.zip">SLaB v0.7</a> (includes source, a sample app, some tests, and binaries) </p>
<ul>
<li>For the latest version, please check out SLaB on my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">Downloads and Samples</a> page. </li>
<li>The v0.7 download of SLaB includes the following changes:
<ul>
<li>Added TryImportResourceDictionary that allows XAML resource dictionaries to be imported but fail quietly (so that if not all dependencies for a control are met, other controls in the library (that share the same generic.xaml) can still be used. </li>
<li>Added XamlDependencyAttribute, which ensures that Xaml-only assembly dependencies can be declared and appear as dependencies in the assembly metadata. </li>
<li>Other minor bugfixes </li>
</ul>
</li>
<li>In the interim (since my last post with SLaB), I also produced the v0.6 version, which had the following changes:
<ul>
<li>Made CollectionPrinter work for controls like DataGrid when they auto-generate columns for generic collections (based on the type in IEnumerable&lt;T&gt;) </li>
<li>Added a utility method that allows you to get the MethodInfo for an arbitrary method, including private ones (from anywhere that the method is accessible) </li>
<li>Other minor bugfixes </li>
</ul>
</li>
</ul>
<p>As always, I’d love to know what you think!</p>
</p>
</li>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>A &#8220;refreshing&#8221; Authentication/Authorization experience with Silverlight 4</title>
		<link>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/</link>
		<comments>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 03:35:28 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ContentLoader]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/</guid>
		<description><![CDATA[At the beginning of the year, as part of a series of posts about the INavigationContentLoader extensibility point in Silverlight 4, I described a way to use a content loader to do authorization before allowing a user to navigate to a page.&#160; With the content loader, you can either throw an exception when an unauthorized [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>At the beginning of the year, as part of a series of posts about the INavigationContentLoader extensibility point in Silverlight 4, <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/">I described a way to use a content loader to do authorization before allowing a user to navigate to a page</a>.&#160; With the content loader, you can either throw an exception when an unauthorized user tries to reach a protected Page, redirect your users to another Page, or return a different page (e.g. a Login page) in its stead.&#160; This makes for a fairly nice experience for your users, wherein they are taken directly to a login page (or at least a page with more information about why they cannot access the given page) when they lack the credentials to reach the page they are requesting.</p>
<p>The trouble with this, however, was that once your application reached the login page and your user attempted to log in, there was no clear/easy/universal way to get the user back to the location he/she was originally requesting.&#160; Ideally, an application would keep its context (i.e. the Uri wouldn’t change) when it sends a user to a login page, and take the user to the restricted content once the right credentials are acquired.</p>
<p>When I wrote my original post, I was aware of this limitation, and didn’t have a great solution for it.&#160; Attempting to re-navigate to the requested page was unhelpful because navigating twice to the same Uri is a no-op.&#160; Starting with the Silverlight 4 RC (and continuing into the RTW release, of course), however, such a solution exists!&#160; We quietly added an API to <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame(VS.95).aspx">Frame</a> and <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice(v=VS.95).aspx">NavigationService</a>: <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice.refresh(v=VS.95).aspx">Refresh()</a>.</p>
<h3>How does refreshing help?</h3>
<p>Calling Frame.Refresh() or NavigationService.Refresh() causes the entire page to be reloaded, meaning that a custom content loader will be called, providing an opportunity to return a different page (or redirect elsewhere).&#160; Without having to make any changes to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a> and the <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/" target="_blank">AuthContentLoader</a> or <a href="http://www.davidpoll.com/2009/12/07/opening-up-silverlight-4-navigation-event-based-and-error-handling-inavigationcontentloaders/" target="_blank">ErrorPageLoader</a>, we can now produce the desired experience!</p>
<p>Now, our ContentLoader XAML looks like this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot;
                    </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
                    </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot;
                                    </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot;
                                    </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot; /&gt;
        &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ExceptionType</span><span style="color: blue">=&quot;UnauthorizedAccessException&quot;
                            </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/Views/LoginPage.xaml&quot; /&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/Views/ErrorPage.xaml&quot; /&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/About\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span><span style="color: blue">=&quot;?&quot; /&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span><span style="color: blue">=&quot;*&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/RegisteredUsersPage\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
</span></pre>
<p>The primary difference between the XAML above and the original XAML I had posted was to remove the ErrorRedirector (which caused redirection to the login page rather than loading the login page in place of the requested page).&#160; Because this was removed, we no longer need nested ErrorPageLoaders (which existed in order to redirect only in the login case, and load the error page without changing the Uri for other errors).&#160; You’ll note that for the About page and the RegisteredUsers page, access is restricted.&#160; When an UnauthorizedAccessException occurs, users will see the LoginPage.</p>
<p>In the login page, all we need to do now is call NavigationService.Refresh() when the user logs in.&#160; My example uses WCF RIA Service’s WebContext find out this information, but you could just as easily attempt to refresh after a ChildWindow is closed or a Login button is clicked.</p>
<p>My LoginPage code looks like this:</p>
<pre class="code"><span style="color: blue">protected override void </span>OnNavigatedTo(<span style="color: #2b91af">NavigationEventArgs </span>e)
{
    <span style="color: #2b91af">WebContext</span>.Current.Authentication.LoggedIn += Authentication_LoggedIn;
}

<span style="color: blue">protected override void </span>OnNavigatedFrom(<span style="color: #2b91af">NavigationEventArgs </span>e)
{
    <span style="color: #2b91af">WebContext</span>.Current.Authentication.LoggedIn -= Authentication_LoggedIn;
}

<span style="color: blue">void </span>Authentication_LoggedIn(<span style="color: blue">object </span>sender, <span style="color: #2b91af">AuthenticationEventArgs </span>e)
{
    <strong><em><u>NavigationService.Refresh();</u></em></strong>
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Yep, that’s all it takes!&#160; Now, when a user logs in (either by clicking the login button on the page or logging in through some other dialog in the application), the Frame’s content is refreshed, and the AuthContentLoader attempts to verify the user’s credentials once again.</p>
<h3>Cool!&#160; Can I see it in action?</h3>
<p>You know I would never leave you without a sample!&#160; Click the image below to see the sample application (based on my <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/">original example</a>, just updated for SL4).&#160; First try navigating to the protected pages without logging in, then try logging in and note how the page automatically is refreshed based upon your new credentials.</p>
<p><strong><em>Login information:</em></strong> Log in with User = “Test”, Password = “_Testing”</p>
<p><a href="http://www.davidpoll.com/Samples/AuthorizingNavigation/ScratchBusinessApplicationTestPage.aspx#/Home" target="_blank"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="A WCF RIA Services application with the AuthContentLoader" border="0" alt="A WCF RIA Services application with the AuthContentLoader" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image5.png" width="644" height="432" /></a></p>
<p>&#160;</p>
<p>You can find the source for this application <a href="http://www.davidpoll.com/Samples/Download/AuthorizingNavigation.zip" target="_blank">here</a>. </p>
<h3>Anything else I should know about Refresh()?</h3>
<p>Without a doubt, Refresh()’s usefulness is not restricted to this scenario.&#160; With custom content loaders, it’s particularly useful to be able to refresh the page, since the page returned as a result of that navigation may change from one attempt to the next.&#160; Even without a custom content loader, Refresh() allows you to create a new instance of a page, making re-initializing the page you’ve navigated to clean and simple.&#160; The behavior is identical to navigating to a new page – the only difference is that the old and new Uris are identical, and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationmode(VS.95).aspx" target="_blank">NavigationMode</a> of the operation is “Refresh”.</p>
<p>Please note: Refresh() will still respect the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.navigationcachemode(v=VS.95).aspx" target="_blank">NavigationCacheMode</a> of the Page and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.cachesize(v=VS.95).aspx" target="_blank">CacheSize</a> of the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame(v=VS.95).aspx" target="_blank">Frame</a>.&#160; If a Page is being cached, calling Refresh() will not create a new instance (but will still cause the Navigating/Navigated events and the corresponding overrides on Page to be raised/called).&#160; To prevent this from happening, set the NavigationCacheMode of the page being refreshed to Disabled before the new page would be loaded (i.e. before Refresh() is called or while handling the Navigating event).</p>
<h3>Is that it?</h3>
<p>Yep, that’s it! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; Let me know what you think!&#160; What else would you like to see?</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Opening up Silverlight 4 Navigation: Authentication/Authorization in an INavigationContentLoader</title>
		<link>http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/</link>
		<comments>http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 08:01:00 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ContentLoader]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/</guid>
		<description><![CDATA[Continuing my series of posts on ways to use INavigationContentLoader (a feature in the Silverlight 4 Beta SDK), in this post, I’ll explore another idea for a composable INavigationContentLoader that protects access to your pages based upon the credentials of the user of your Silverlight application.&#160; To demonstrate its use, I’m using a WCF RIA [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Continuing my <a href="http://www.davidpoll.com/tag/contentloader/">series of posts</a> on ways to use INavigationContentLoader (a feature in the Silverlight 4 Beta SDK), in this post, I’ll explore another idea for a composable INavigationContentLoader that protects access to your pages based upon the credentials of the user of your Silverlight application.&#160; To demonstrate its use, I’m using a <a href="http://www.silverlight.net/riaservices">WCF RIA Services</a> application (purely for their Authentication/Authorization provisions).</p>
<p>The basic problem is this: as you would with a website, you build an application with multiple pages – some of which are intended for anonymous users or users in a particular role and some are intended for users with greater privileges.&#160; How do you prevent such users from navigating to those pages and give them an appropriate user experience if they do try to reach pages for which they are not authorized?</p>
<p>To that end, I’ve added another INavigationContentLoader to my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">SLaB</a> examples – the “AuthContentLoader” – that checks to see whether your user is authorized to view a page before navigating to it.&#160; If the user is <strong><em>not</em></strong> authenticated, the AuthContentLoader throws, resulting in a NavigationFailed event on the Frame/NavigationService that you can handle in order to provide better feedback to your users if there is an UnauthorizedAccessException.</p>
<h3>Cool – How does it work?</h3>
<p>If you’re familiar with authorization with ASP.NET (settings you might add to your web.config file), this ContentLoader’s use should come pretty easily to you.&#160; For example, in ASP.NET, you might have the following in your web.config:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">allow </span><span style="color: red">roles</span><span style="color: blue">=</span>&quot;<span style="color: blue">Role1, Role2</span>&quot; <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">allow </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">SuperUser</span>&quot;<span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">deny </span><span style="color: red">roles</span><span style="color: blue">=</span>&quot;<span style="color: blue">Role3, Role4</span>&quot; <span style="color: red">users</span><span style="color: blue">=</span>&quot;<font color="#0000ff">LessImpressive</font><span style="color: blue">User</span>&quot; <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">deny </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">?</span>&quot; <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">allow </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">*</span>&quot;<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>I tried to keep the API for the AuthContentLoader quite similar.&#160; With the AuthContentLoader, you can:</p>
<ul>
<li>Allow or deny users access to pages that match a Regular Expression (allowing you to scope the authorization to particular pages) </li>
<li>Allow or deny users access to pages based upon their roles, authentication status, and user name </li>
<li>Wrap any other INavigationContentLoader in order to protect access </li>
</ul>
<p>To accomplish this, there are just a few steps:</p>
<ol>
<li>Set your Frame.ContentLoader to an AuthContentLoader. </li>
<li>Bind AuthContentLoader.Principal to any IPrincipal (in my example, I’ll use the <a href="http://code.msdn.microsoft.com/RiaServices/Release/ProjectReleases.aspx?ReleaseId=2661">built-in authentication context in WCF RIA Services</a>).&#160; This is what the ContentLoader uses to check the user’s credentials. </li>
<li>Add rules for your pages.&#160; If no rule matches a page, the page is assumed to be broadly accessible. </li>
</ol>
<p>Put all of this together, and you end up with something like this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame ...</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
<strong><em>        &lt;</em></strong></span><strong><em><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span></em></strong><strong><em><span style="color: blue">}}&quot;&gt;
            &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span></em></strong><strong><em><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span></em></strong><strong><em><span style="color: blue">=&quot;^/Views/About\.xaml\??.*$&quot;&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span></em></strong><strong><em><span style="color: blue">=&quot;?&quot; /&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span></em></strong><strong><em><span style="color: blue">=&quot;*&quot; /&gt;
                &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span></em></strong><strong><em><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span></em></strong><strong><em><span style="color: blue">=&quot;^/Views/RegisteredUsersPage.xaml\??.*$&quot;&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Roles</span></em></strong><strong><em><span style="color: blue">=&quot;Registered Users&quot; /&gt;
                &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span></em></strong><strong><em><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span></em></strong><strong><em><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span></em></strong><span style="color: blue"><strong><em>&gt;</em></strong>
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
</span></pre>
<p>Here, we have rules for About.xaml (with any querystring) and RegisteredUsersPage.xaml (again, with any querystring).&#160; Note that the UriPattern is a <a href="http://msdn.microsoft.com/en-us/library/hs600312(VS.71).aspx">Regex</a>, and must also take into account the possible query strings that could be attached to the request.&#160; I know it looks a little arcane, but it does the trick, and allows you to specify whole sets of Uri’s that share the same authorization characteristics (e.g. any page in the “PrivateViews” folder could be restricted to Administrators).</p>
<p>The XAML snippet above places restrictions on two pages:</p>
<ul>
<li>About.xaml – anonymous (Principal == null || Principal.Identity == null || Principal.Identity.IsAuthenticated == false) users are denied, and all other users are allowed </li>
<li>RegisteredUsersPage.xaml – only users that belong to the “Registered Users” role are allowed </li>
<li>Users are granted access to all other pages </li>
</ul>
<p>Like the ErrorPageLoader, the AuthContentLoader can take another ContentLoader (but defaults to the PageResourceContentLoader if none is specified), and will delegate the actual loading (after the user has been authorized) to that loader.</p>
<p>And there you go!&#160; Easy as pie!&#160; Feel free to give it a try and play around with it!&#160; Happy New Year!</p>
<h3>Wait!&#160; Don’t stop yet!&#160; Please tie this back to your other posts!</h3>
<p>Relax!&#160; I won’t leave you hanging!&#160; After all, what’s the point of having <strong>two</strong> composable INavigationContentLoaders (AuthContentLoader and <a href="http://www.davidpoll.com/2009/12/07/opening-up-silverlight-4-navigation-event-based-and-error-handling-inavigationcontentloaders/">ErrorPageLoader</a>) if you’re not going to use them together? <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I made a very specific choice with the AuthContentLoader: when the user doesn’t have permission to access a page, the AuthContentLoader throws an exception.&#160; That’s <strong><em>very</em></strong> convenient when you want to use the ErrorPageLoader to handle authentication failures.&#160; The AuthContentLoader, by default, throws an UnauthorizedAccessException, so we can handle that exception explicitly using the ErrorPageLoader.&#160; In this case, we’ll <strong><em>redirect</em></strong> users who visit an unauthorized page to another page that directs them to log in.&#160; The XAML for this follows:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span>&gt;
<em><strong>    &lt;errorLoader</strong></em></span><span style="color: blue"><em><strong>:</strong></em></span><em><strong><span>ErrorPageLoader.ErrorPages&gt;
        &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red"><u>ExceptionType</u></span><span style="color: blue"><u>=&quot;UnauthorizedAccessException&quot;</u> </span></strong></em><em><strong><span><u>ErrorPageUri=&quot;/LoginPage&quot;</u> /&gt;
    &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span></strong></em><span><em><strong>ErrorPageLoader.ErrorPages&gt;</strong></em>
<strong><em>    &lt;</em></strong></span><strong><em><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span></em></strong><strong><em><span style="color: blue">&gt;
        <u>&lt;</u></span><u><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorRedirector </span></u></em></strong><strong><em><span style="color: blue"><u>/&gt;</u>
    &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span></em></strong><span style="color: blue"><strong><em>&gt;</em></strong>
    &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;&gt;
            &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/About\.xaml\??.*$&quot;&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span><span style="color: blue">=&quot;?&quot; /&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span><span style="color: blue">=&quot;*&quot; /&gt;
                &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/RegisteredUsersPage.xaml\??.*$&quot;&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot; /&gt;
                &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
</span></pre>
<p>Cool!&#160; Now, if users navigate to a page they’re not authorized to see, they’ll be redirected to a login page!&#160; Note the exception type being handled (UnauthorizedAccessException), the ErrorPageUri (unmapped, because we’re using the ErrorRedirector, which will cause a brand new navigation to take place – including mapping), and the use of the ErrorRedirector to redirect to a new Uri rather than just loading alternate content (allowing the user to come back to the page rather than assuming that the login page is the real content).</p>
<p>Ok, we’re now in pretty good shape, but users can still hit problems besides the UnauthorizedAccessException, such as attempting to load a page that does not exist.&#160; In my last post, we solved this using an ErrorPageLoader, and we’ll do the same this time.&#160; In these cases, I actually do want to load alternate content rather than redirect to an error page, since this is the typical experience with web error pages (e.g. a 404 page).&#160; I can accomplish this by adding a <strong><em>second</em></strong> ErrorPageLoader to the mix, like so:</p>
<pre class="code"><strong><em><span style="color: blue">&lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span></em></strong><strong><em><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorPages</span></em></strong><strong><em><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ErrorPageUri</span></em></strong><strong><em><span style="color: blue">=&quot;/Views/ErrorPage.xaml&quot; /&gt;
    &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorPages</span></em></strong><strong><em><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span></em></strong><span style="color: blue"><strong><em>&gt;</em></strong>
        &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorPages</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ExceptionType</span><span style="color: blue">=&quot;UnauthorizedAccessException&quot; </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/LoginPage&quot; /&gt;
            &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorPages</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorRedirector </span><span style="color: blue">/&gt;
            &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;&gt;
                    &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/About\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span><span style="color: blue">=&quot;?&quot; /&gt;
                            &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span><span style="color: blue">=&quot;*&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/RegisteredUsersPage\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">authLoader</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
    <strong><em>&lt;/</em></strong></span><strong><em><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span></em></strong><strong><em><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">errorLoader</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span></em></strong><span style="color: blue"><strong><em>&gt;</em></strong>
</span></pre>
<p>And that’s it!&#160; Now, when users access your site, they’re protected from any type of error and have access restricted appropriately!&#160; Give it a shot with my <a href="http://www.davidpoll.com/Samples/AuthorizingNavigation/ScratchBusinessApplicationTestPage.aspx#/Home">live sample application</a>:</p>
<p><strong><em>Note:</em></strong> Log in with User = “Test”, Password = “_Testing”</p>
<p><strong><em>Also Note:</em></strong> I’ve been having a little trouble with my server, so if this doesn’t work for you, feel free to try downloading and running the code locally (see below for a link).</p>
<p><a href="http://www.davidpoll.com/Samples/AuthorizingNavigation/ScratchBusinessApplicationTestPage.aspx#/Home"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Live Sample Application" border="0" alt="Live Sample Application" src="http://www.davidpoll.com/wp-content/uploads/2009/12/image2.png" width="637" height="484" /></a></p>
<p>First, try clicking on the restricted links at the top of the application and observe the login page that appears.&#160; Next, click the broken link (or type something random into your browser after the “#” in the URL), and observe the error page that appears.&#160; Now, log in to the application (feel free to create your own account or use the test account above – any account should give you access to the pages that are currently restricted), and try visiting those pages again!</p>
<h3></h3>
<h3>Ok, I think I’m beginning to get it.&#160; Give me the goods so I can go play with it!</h3>
<p>As always, I can’t leave you empty-handed.&#160; I’ve added the AuthContentLoader to SLaB, which you can download to get both binaries and code.&#160; I’ve also included the source (which requires <a href="http://www.silverlight.net/riaservices">WCF RIA Services</a> and the Silverlight 4 Beta) for the demo application I linked to above:</p>
<ul>
<li><a href="http://www.davidpoll.com/Samples/AuthorizingNavigation/ScratchBusinessApplicationTestPage.aspx#/Home">Live Sample</a> (<a href="http://www.davidpoll.com/Samples/Download/AuthorizingNavigation.zip">source</a>) </li>
<li><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.0.2.zip">SLaB v0.0.2</a> (includes source, a sample app, some tests, and binaries)
<ul>
<li>For the latest version, please check out SLaB on my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">Downloads and Samples</a> page. </li>
<li>The v0.0.2 download of SLaB includes:
<ul>
<li>AuthContentLoader and related classes </li>
<li>ErrorPageLoader moved into its own assembly (to keep its size down) </li>
</ul>
</li>
</ul>
</li>
</ul>
<h3></h3>
<h3>In Conclusion&#8230;</h3>
<p>In my humble opinion, there is a lot of power in composing these types of INavigationContentLoaders.&#160; With the AuthContentLoader, you can prevent Uri’s from being loaded in the context of your application.&#160; Whether you’re just trying to provide a good user experience or actually prevent users from reaching certain Uri’s (e.g. dynamically downloaded XAPs/assemblies that should only be accessible if you’re logged in) a ContentLoader like this could be useful.&#160; The AuthContentLoader works well with WCF RIA Services, which provides easy access through its “WebContext” concept to a User that represents both an IPrinciple and an IIdentity.&#160; Stay tuned for more ideas – I’m still working on some fun little experiments.&#160; Hopefully these posts inspire some cool ideas!&#160; If you’ve got ‘em, I’d love to hear ‘em!</p>
<p><strong>Remember</strong>, SLaB is just a collection of the samples and experimental components I’ve been putting together so that they’re all in one place.&#160; I can’t make any guarantees about maintaining them, fixing bugs, not making breaking changes, etc., but you’re more than welcome to try them out, use them, and let them inspire your development (or show you what <em>not</em> to do if you really dislike something I’m doing!) <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<h3></h3>
<h3>Disclaimer</h3>
<p>The AuthContentLoader <strong><em>does not</em></strong> protect your data in any way – it simply provides a user experience around navigating to pages that may have restricted access.&#160; Users can still open up your XAP and see its contents (so the XAML/code for those restricted pages isn’t protected), but it does do an effective job of limiting what users are able to access within your application.&#160; You should still be aggressively securing your application if need be.&#160; <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Don’t you have something else to say?</h3>
<p>Oh, yeah!&#160; Happy New Year!&#160; Here’s to (and good riddance to) the noughties, bring on the teens!&#160; I hope you all have had a wonderful holiday season, and enjoy prosperity in the year ahead.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 and building business applications (PDC09-CL19)</title>
		<link>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/</link>
		<comments>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 17:28:56 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[CollectionView]]></category>
		<category><![CDATA[Data Binding]]></category>
		<category><![CDATA[PDC]]></category>
		<category><![CDATA[PDC09]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Validation]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/</guid>
		<description><![CDATA[Hi everyone!&#160; Wow – yesterday was a big day, with a lot of amazing announcements at PDC ‘09 – especially the announcement that the Silverlight 4 Beta was publicly available.&#160; I was very excited to be given an opportunity to give a talk at PDC this year, and it was a real treat.&#160; My talk [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Hi everyone!&#160; Wow – yesterday was a big day, with a lot of amazing announcements at <a href="http://www.microsoftpdc.com">PDC ‘09</a> – especially the announcement that the <a href="http://www.silverlight.net/getstarted/silverlight-4-beta/">Silverlight 4 Beta was publicly available</a>.&#160; I was very excited to be given an opportunity to give a talk at PDC this year, and it was a real treat.&#160; My talk – <a href="http://microsoftpdc.com/Sessions/CL19">Building Line of Business Applications with Silverlight 4 (PDC09-CL19)</a> – focused on the new features in Silverlight 4 that are particularly useful in business applications, especially those that are data-centric. <em>(Please ignore the abstract given on that page for the talk – it wasn’t updated properly from a change we made to it early on! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</em></p>
<p><img style="border-right-width: 0px; margin: 0px 0px 10px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="After the announcement of Silverlight 4, my talk appeared on the big board!" border="0" alt="After the announcement of Silverlight 4, my talk appeared on the big board!" align="right" src="http://www.davidpoll.com/Images/Silverlight4andbuildingbusinessapplicati_82ED/43685563_3.jpg" width="287" height="475" /></p>
<p>The talk covered a wide array of features, but I broke things down into three conceptual categories around data:</p>
<ul>
<li>Data Interactivity (i.e. how do I drill down into my data to find what I’m looking for?) </li>
<li>Data Entry (i.e. how do users add/edit data and what kind of feedback do you give them to minimize mistakes?) </li>
<li>Data Presentation (i.e. how do I communicate data to a user, but also how do I communicate intent for data entry, such as “choose from this list of options” to a user?) </li>
</ul>
<p>The Silverlight 4 features I covered generally fit into these categories:</p>
<ul>
<li>Data Interactivity
<ul>
<li>Data sources window (VS2010) </li>
<li>Selector support (i.e. SelectedValue/SelectedValuePath on ComboBox and related controls) </li>
<li>Binding TargetNullValue </li>
<li>Binding FallbackValue </li>
<li>ICommand support on ButtonBase (i.e. Command and CommandParameter) and Hyperlink </li>
</ul>
</li>
<li>Data Entry
<ul>
<li>Asynchronous validation </li>
<li>Cross-field validation </li>
</ul>
</li>
<li>Data Presentation
<ul>
<li>Binding StringFormat </li>
<li>CollectionViewSource Grouping </li>
<li>Printing and pagination </li>
<li>DataGrid * Columns (*-based column sizing, as with the Grid control) </li>
</ul>
</li>
</ul>
<p>And all of this is just the short list of features I could cover in my 50-minute talk!&#160; There are certainly other business application-friendly features out there, but more importantly, the feature list for Silverlight 4 is just <a href="http://www.silverlight.net/getstarted/silverlight-4-beta/#whatsnew">huge</a>!&#160; The talk also used <a href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx">Visual Studio 2010 Beta 2</a>, which provides an awesome development environment for Silverlight.</p>
<p>I won’t go into too much detail here, but I wanted to share out my powerpoint deck and sample/demo code so that those who were in attendance at the talk can look back for reference, and those that weren’t can see what they were missing.&#160; I don’t know for sure yet, but I think there will be a webcast of the talk online at some point, and I’ll be happy to link to that once it’s available.</p>
<p>So, without further ado, here are the links:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/CL19_POLL.pptx">PDC ‘09 PPT deck</a> </li>
<li>Issue tracker demo application (<a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">source</a>) </li>
</ul>
<p>Before I leave you, I’d like to just give a brief overview of the sample application.&#160; The application itself is an issue tracker – allowing you to file bugs/issues, assign them to people, resolve the bugs, etc.&#160; It has 4 functional pages:</p>
<ul>
<li>New Issue
<ul>
<li>Allows users to file a new bug/issue </li>
</ul>
</li>
<li>All Issues
<ul>
<li>Allows users to see a list of all bugs in the database </li>
</ul>
</li>
<li>My Issues
<ul>
<li>Allows users to see un-fixed issues that are assigned to them </li>
</ul>
</li>
<li>Reports
<ul>
<li>Allows users to see a report of all of the issues in the database and print them if he/she so desires </li>
</ul>
</li>
</ul>
<p>The application was built using LINQ-to-SQL and <a href="http://www.silverlight.net/getstarted/riaservices/">WCF RIA Services</a> (formerly .NET RIA Services), which made getting off the ground with real data running on a real database extremely quick and easy.&#160; If you’re still around at PDC, there are a few talks later today on RIA Services by <a href="http://blogs.msdn.com/brada">Brad Abrams</a> and <a href="http://blogs.msdn.com/dinesh.kulkarni/">Dinesh Kulkarni</a> you should check out.</p>
<p>A few things to try in the application (some of which I didn’t go over in the talk):</p>
<ul>
<li>Right-click and change the theme of the application
<ul>
<li>Many thanks to my co-worker <a href="http://www.jebishop.com/">Jesse Bishop</a> for his <a href="http://www.jebishop.com/2009/11/18/implementing-a-contextmenu-in-silverlight-4-beta/">ContextMenu control</a> </li>
<li>This feature uses implicit styles (new in SL4) to change the entire look of the application </li>
</ul>
</li>
<li>Set the priority on a bug to be lower than (i.e. a larger number than) severity and see the validation UI (cross-field validation) </li>
<li>Set the title of an issue to be something wholly contained in another issue’s title to see the validation UI (asynchronously querying the server for “similar” bugs) </li>
<li>Drag and drop a file from your disk into the list of files on a bug (one of the tabs at the bottom) </li>
<li>Print out a set of reports on the reports page (click the “Print” button) </li>
<li>Set a value in the “Tags” field and then change it in the DataGrid under the Attributes tab on a bug, noticing that they stay in sync (thanks to bindings to string indexers) </li>
<li>Use the mouse-wheel almost anywhere and note that it works without any code to make it happen! </li>
<li>Explore the code!&#160; I know there are some bugs in the application and in our beta product, but the hope is to give you an idea of how you can use these features in a business application.&#160; I’m sure there will be lots of content out there about all of these features – but this should help introduce you to them! </li>
</ul>
<p>Well, thanks again everyone who was able to join me for my talk, and to all those who’ve been following me on twitter through this exciting announcement.&#160; Let me know if you have questions or if there’s anything you’d like me to expand on, and I’ll be more than happy to chime in!</p>
<p>&#160;</p>
<p><em>Links to materials repeated here for convenience:</em></p>
<ul>
<li><a href="http://www.davidpoll.com/Download/CL19_POLL.pptx">PDC ‘09 PPT deck</a> </li>
<li>Issue tracker demo application (<a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">source</a>) </li>
</ul>
<p><strong><em>Update (11/19/2009): </em></strong>Video of the talk is now available here: <a title="http://microsoftpdc.com/Sessions/CL19" href="http://microsoftpdc.com/Sessions/CL19">http://microsoftpdc.com/Sessions/CL19</a></p>
<p><strong><em>Update (11/20/2009): </em></strong>Video of the talk is embedded below:</p>
<p> <object data="data:application/x-silverlight-2," height="337.5" type="application/x-silverlight-2" width="600"><param name="source" value="http://microsoftpdc.com/Skins/PDC09/Styles/players/VideoPlayer2009_03_27.xap" /><param name="initParams" value="m=http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/CL19.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://microsoftpdc.com/Skins/PDC09/Styles/images/DefaultPlayerBackground.png, postid=0" /><param name="background" value="#00FFFFFF" /><a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> 	 	<img alt="Get Microsoft Silverlight" src="http://go.microsoft.com/fwlink/?LinkId=108181" style="border-style: none" /> 	 	</a> </object>
<p>P.S.&#160; Sorry for the lack of posts recently – I’ve got a bunch of new topics lined up, but it was a pity not to be able to write about Silverlight 4 before it was announced.&#160; Expect another series on Navigation coming soon!</p>
<p>&#160;</p>
<p><em><strong>Update (12/21/2009):</strong> </em>I think I’ve figured out the issue people were having with the downloaded project.</p>
<p>If you’re receiving an error like this when you try to build my project:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2009/12/image.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Error	4	The &quot;ValidateXaml&quot; task failed unexpectedly." border="0" alt="Error	4	The &quot;ValidateXaml&quot; task failed unexpectedly." src="http://www.davidpoll.com/wp-content/uploads/2009/12/image_thumb.png" width="644" height="205" /></a> </p>
<p>This is happening because Windows protects you from downloaded files by default (VS2010 will warn you when you open the project that they come from “untrusted sources.”&#160; Fixing this is pretty straightforward.</p>
<ol>
<li>Download the <a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">zip</a>.</li>
<li>Right-click the downloaded zip file and choose “Properties”</li>
<li>At the bottom of the “General” tab, there is a “Security” section, saying “This file came from another computer and might be blocked to help protect this computer.”&#160; Click the “Unblock” button.     <br /><a href="http://www.davidpoll.com/wp-content/uploads/2009/12/image1.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Click the &quot;Unblock&quot; button." border="0" alt="Click the &quot;Unblock&quot; button." src="http://www.davidpoll.com/wp-content/uploads/2009/12/image_thumb1.png" width="381" height="519" /></a> </li>
<li>Unzip and open the solution.</li>
<li>Build and run!</li>
</ol>
<p>Sorry it took me so long to figure this one out!&#160; It had me stumped for a while.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
<enclosure url="http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/CL19.wmv" length="669448911" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Update 2: Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 07:45:50 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Silverlight 3]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/</guid>
		<description><![CDATA[Hi folks!&#160; It’s been a little while since I’ve blogged, but fear not, I’m still watching and hoping to blog more in the coming weeks. In the meantime, it’s been brought to my attention by a few people now that there are a few issues with the Activity control, and I wanted to address them. [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Hi folks!&#160; It’s been a little while since I’ve blogged, but fear not, I’m still watching and hoping to blog more in the coming weeks.</p>
<p>In the meantime, it’s been brought to my attention by a few people now that there are a few issues with the Activity control, and I wanted to address them.</p>
<ol>
<li>Performance – A bit of a mea culpa on my part.&#160; I included a feature for the control that I’ve called “AutoBind”, whereby it would watch for changes to the visual tree of its contents and subscribe to any control that has a property whose name matches “ActivityPropertyName”.&#160; By default, this is great when working with .NET RIA Service’s DomainDataSource, since ActivityPropertyName is “IsBusy” by default, but it also turns out to be a hefty amount of work, constantly searching the visual tree and registering/unregistering event handlers.&#160; This wouldn’t be so bad, except that AutoBind defaults to true, meaning even if you’re not using this functionality, the Activity control is doing the work.&#160; Below, you’ll find a new version of the Activity control that amends the situation, making AutoBind default to false.&#160; This is the only change to the control since my last post on the matter, but I’d love to hear if you have thoughts about the control, this feature, or other requests!</li>
<li>.NET RIA Services’ Business Application Template – So, the .NET RIA Services guys included with their <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en">July Preview</a> a project template to help you get started with a RIA Services application.&#160; In this template, they included a dll with the Activity control in it.&#160; A few people have noted that it has a slightly different API than they’re used to seeing with the control, which is due to their use of the original version of the control that I posted (its API has changed a bit since then, and a number of bugs were fixed, including some layout issues).&#160; Anyhoo, feel free to pick up the latest version below!</li>
</ol>
<p>So there you have it – just a few changes and things to note.&#160; You can find the control here:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/ActivityControl9-14.zip">Activity Control</a></li>
<li><a href="http://www.davidpoll.com/Download/ActivityControlDemo9-14.zip">Activity control demo project</a></li>
</ul>
<p>Thanks for all the great feedback since I first posted this control.&#160; As usual, let me know if you have questions or issues!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Update: Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 19:59:10 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 3 Beta]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/?p=73</guid>
		<description><![CDATA[Well, it’s been a while since I first posted on this, but the feedback was incredible, and I got some great suggestions.&#160; As a result, I’ve updated the Activity control and (finally) have a running sample on the web!&#160; The fundamental idea of the control has remained the same, as well as the mechanisms by [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Well, it’s been a while since I <a href="http://www.davidpoll.com/?p=4" target="_blank">first posted</a> on this, but the feedback was incredible, and I got some great suggestions.&#160; As a result, I’ve updated the Activity control and (finally) have a running sample on the web!&#160; The fundamental idea of the control has remained the same, as well as the mechanisms by which it can work.&#160; It’s still a prototype, but a very useful one at that!</p>
<p>To see the Activity control in action, take a look here: <a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx" target="_blank">Activity Control Demo</a></p>
<p>The demo requires the Silverlight 3 beta to be installed on your machine, which can be found here: <a title="http://silverlight.net/getstarted/silverlight3/default.aspx" href="http://silverlight.net/getstarted/silverlight3/default.aspx">http://silverlight.net/getstarted/silverlight3/default.aspx</a></p>
<p>The demo application shows two examples of using the Activity control to display async/background activity (click the images for deep-links into the Silverlight application):</p>
<ul>
<li>With <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en" target="_blank">.NET RIA Services</a> and the DomainDataSource, the Activity control uses element-to-element binding to indicate to the user that data is being loaded or submitted.&#160; The demo page is running live on my server using the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&amp;displaylang=en" target="_blank">Northwind sample database</a>.&#160; Those of you who think you can play some dirty tricks by overwriting the data on my server (yes, I provided insert/update/delete functionality) – any attempts to do so will be quickly foiled, since the server will accept the requests, but ignore them! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </li>
</ul>
<p><a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx#/RiaServicesActivity" target="_blank"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title=".NET RIA Services with the Activity Control" border="0" alt=".NET RIA Services with the Activity Control" src="http://www.davidpoll.com/wp-content/uploads/2009/06/image.png" width="604" height="329" /></a></p>
<ul>
<li>Any background activity might warrant using the activity control.&#160; The second example I’ve provided uses the activity control while I use a simple statistical method of approximating PI (yes, very geeky).&#160; It takes millions of iterations to get a mediocre approximation of PI (I know, I’m not using an efficient method, but it does do a lot of work!).&#160; Here, I’ve augmented the Activity control to allow the work to be stopped/cancelled: </li>
</ul>
<p><a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx#/HeavyAsyncWork" target="_blank"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Calculating PI with background activity" border="0" alt="Calculating PI with background activity" src="http://www.davidpoll.com/wp-content/uploads/2009/06/image1.png" width="604" height="329" /></a></p>
<p>&#160;</p>
<p>So by now I’m sure you’re asking: “What’s changed?”&#160; Well, let me tell you!</p>
<ul>
<li>Thanks to feedback from a variety of folks, I’ve removed the all-encompassing template that included the pop-up window.&#160; That’s now baked into the control template.&#160; If you’d like to change it, you can use the <a href="http://www.microsoft.com/expression/try-it/blendpreview.aspx">Blend 3 Preview</a> to re-template the control.&#160; In its place, I’ve added:
<ul>
<li>A style for the progress bar.&#160; If you’d like to hide it, use a style to collapse the progress bar. </li>
<li>A means for setting “ActiveContent”.&#160; The Activity control works sort of like a HeaderedContentControl.&#160; You now have ActiveContent and ActiveContentTemplate, which allow you to define in XAML what should appear above the progress bar.&#160; You can put any content you like here, and it’s how I added the cancel button in my PI calculation example.&#160; This is also great because it allows you to easily change the text from “Loading…” to whatever you prefer simply be setting the ActiveContent property to the string of your choice! </li>
</ul>
</li>
<li>The default template for the ActivityControl now sets IsHitTestVisible and IsEnabled to false on its content immediately when IsActive becomes true.&#160; In my old prototype, this only happened when the Activity UI became visible, which meant users could continue to interact with the content while it was busy – a potentially dangerous combination if the user’s interactions can be overriden by the asynchronous work (such as editing values in a DataGrid when the data is being reloaded).&#160; This was from a suggestion by Luke Tigaris in the comments on my last post.&#160; Let me know what you think! </li>
<li>You can now call ResetActivity() on the control to force it to honor the visibility of the control immediately rather than enforcing the display delay and minimum display time.&#160; This way, if a user cancels the background work, you can force the Activity UI to be hidden immediately. </li>
</ul>
<p>&#160;</p>
<p>Anyhoo, let me know what you think of the changes!&#160; I’ve gotten lots of great feedback on the control so far, and I’m sure folks will come up with more as time goes on.</p>
<ul>
<li>You can download the source for the control here: <a href="http://www.davidpoll.com/Download/ActivityControl6-11.zip">Activity Control Source</a> </li>
<li>You can also download the source for the demo here: <a href="http://www.davidpoll.com/Download/ActivityControlDemo.zip">Activity Control Demo</a> </li>
</ul>
<p>For both of these, you’ll need the <a href="http://silverlight.net/getstarted/silverlight3/default.aspx">Silverlight 3 Beta</a>.&#160; The Demo application is built using <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en" target="_blank">.NET RIA Services</a>.</p>
<p>P.S.&#160; Big thanks again to <a href="http://blogs.msdn.com/corrinab/">Corrina</a> for providing the <a href="http://blogs.msdn.com/brada/archive/2009/03/31/silverlight-3-navigation-application-template-extra-themes-posted.aspx">beautiful theme</a> I used in my application.</p>
<p>P.P.S.&#160; Isn’t navigation and deep-linking in the Silverlight 3 Beta cool?&#160; That’s how I made those images link directly to the corresponding pages of my demo application.&#160; I may post more on this in the future.&#160; In the meantime, take a look at the code to see just how little it took to accomplish that! (hint: MainPage.xaml in the Silverlight Navigation Application project template that’s included with the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=11dc7151-dbd6-4e39-878f-5081863cbb5d&amp;displaylang=en">Silverlight 3 Beta Tools for Visual Studio</a> has pretty much everything that’s required)</p>
<p><strong><em>Update 9/14/2009 – </em></strong>I’ve made a small update to the Activity control to fix a performance issue.&#160; You can find it <a href="http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/">here</a>.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 21:32:08 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Well, I told you there would be exciting news at MIX!&#160; After months of working on Silverlight 3 Beta 1, it’s finally available for you to try!&#160; Also coming live for MIX is the “.NET RIA Services” March 2009 Preview, which will assist in building multi-tiered applications and provides end-to-end support for things like data [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Well, I told you there would be exciting news at MIX!&#160; After months of working on <a href="http://silverlight.net/getstarted/silverlight3/default.aspx">Silverlight 3 Beta 1</a>, it’s finally available for you to try!&#160; Also coming live for MIX is the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce">“.NET RIA Services” March 2009 Preview,</a> which will assist in building multi-tiered applications and provides end-to-end support for things like data validation, authentication, and roles, as well as data access.</p>
<p>With the Silverlight 3 beta, you can build really rich user experiences for the web.&#160; For the beta, we’ve added a number of controls and features to enable rich experiences when working with data (e.g. an DataForm, DataPager, ErrorSummary, an updated DataGrid, etc.), and the .NET RIA Services preview makes it much easier to bring the data on your servers down to your Silverlight client.</p>
<p>All of this presents a fairly common problem: what should you do with your UI while data is being loaded or work is being done in the background?&#160; If the amount of work done or data to load is small and completes quickly, it would probably make sense to leave the experience uninterrupted for the user.&#160; For larger amounts of work, however, leaving the user with an unresponsive UI or worse with a responsive UI that doesn’t work properly because data is in the midst of being reloaded is less than ideal.</p>
<p>Imagine, for example, that you’re using a DataGrid whose data takes 3 seconds to load (without taking any explicit steps to show activity).&#160; When your user first loads his application, he sees this:</p>
<img class="size-full wp-image-26  " title="Startup loading without any indicators" alt="image_21" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_21.png" width="576" height="401" />
<p>Not a terribly appealing user experience.&#160; Is the data loading?&#160; What is the user allowed to do with the app right now?&#160; One could show a progress bar somewhere on the screen, but how do you tell the user not to touch the DataGrid until the data is fully loaded?</p>
<p>In the above application, the data is paginated in order to keep the load sizes small and thus speed up the browsing experience.&#160; As a result, moving from page to page may cause load operations to happen as well.&#160; At this point, it is clear that something is strange with the user experience during a page change.&#160; The user would see something like this:</p>
<img class="size-full wp-image-27  " title="Pages changing without activity UI" alt="image_41" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_41.png" width="576" height="401" />
<p>Even though the data in the DataGrid is the previous page’s data, everything is still interactive.&#160; I can navigate from item to item and attempt to make changes, but in a few seconds everything will be wiped out when the data finishes loading.</p>
<p>There are a number of options for dealing with this:</p>
<ul>
<li>Progress bar </li>
<li>Enable/disable controls </li>
<li>Show/hide controls </li>
<li>Combinations of these </li>
</ul>
<p>I’ve been playing around with a slightly different idea: an “Activity” control.&#160; This is a control that displays activity (when appropriate) over its content.&#160; During active periods, it adds an overlay to its wrapped controls, graying them out, disabling them, and displaying a progress indicator, like so:</p>
<img class="size-full wp-image-28   " title="Using the Activity control" alt="image_61" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_61.png" width="576" height="397" />
<p>This way, the user knows which controls he can interact with, and he is also given some additional information (“Loading…” in this case) about why the application is busy.</p>
<p>The control I’m experimenting with itself is pretty straightforward.&#160; Some of its more important features:</p>
<ul>
<li>IsActive property – this can be bound to a boolean value that represents activity.&#160; With .NET RIA Services’ DomainDataSource, this is the “IsBusy” property. </li>
<li>DisplayAfter property – this allows you to set a minimum amount of “active” time before the activity UI appears.&#160; This way, tiny bouts of activity don’t interrupt your user’s workflow. </li>
<li>MinDisplayTime property – this allows you to set a minimum amount of time to display the activity UI.&#160; This way, users have enough time to digest why their screen changed, and the activity UI won’t just flash on and off the screen. </li>
<li>AutoBind/ActivityPropertyName – if AutoBind is set to true (which is the default), the control will search its content for controls that have a property with the name specified (“IsBusy” by default), and will automatically hook itself up to display activity whenever any of its children are busy.&#160; If no such children are found, the control will just use its IsActive property. </li>
<li>ActiveContentTemplate property – allows you to set what is actually displayed (and defaults to what you see above!) </li>
</ul>
<p>With this combination of features, the control makes it easy to add activity UI to your application.&#160; In particular, it works pretty well with the DomainDataSource for .NET RIA Services, since it’s really easy to use ElementName binding to bind IsActive to the IsBusy property on the DDS.&#160; Furthermore, if the DDS is actually inside of the activity control, it will automatically pick up the DDS’s activity:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;2*&quot; /&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;*&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;northwindData&quot;
                              </span><span style="color: red">LoadMethodName</span><span style="color: blue">=&quot;LoadProducts&quot;
                              </span><span style="color: red">LoadSize</span><span style="color: blue">=&quot;20&quot;
                              </span><span style="color: red">AutoLoad</span><span style="color: blue">=&quot;True&quot;&gt;
            &lt;</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource.DomainContext</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">northwind</span><span style="color: blue">:</span><span style="color: #a31515">NorthwindDomainContext </span><span style="color: blue">/&gt;
            &lt;/</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource.DomainContext</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;
                       </span><span style="color: red">CanUserSortColumns</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">HasChanges</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData, </span><span style="color: red">Converter</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">boolConverter</span><span style="color: blue">}}&quot;&gt;
        &lt;/</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;1&quot;
                               </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
        &lt;/</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;</span></pre>
<p>Otherwise, it’s a simple matter of using ElementName binding to wire up your activity UI:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity </span><span style="color: red">IsActive</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">IsBusy</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
    &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;2*&quot; /&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;*&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;
                       </span><span style="color: red">CanUserSortColumns</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">HasChanges</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData, </span><span style="color: red">Converter</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">boolConverter</span><span style="color: blue">}}&quot;&gt;
        &lt;/</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;1&quot;
                               </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
        &lt;/</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;</span></pre>
<p>With this control, it’s easy to have multiple controls all show activity at the same time (either by wrapping them all with the Activity control or by binding activity controls to the same value), and the “busy” experience can be consistent across the app.</p>
<p>This is just a simple prototype control, but I’d love to hear what you think!&#160; Is there something important that’s missing?&#160; Are there other user experience deficiencies you see (either when using SL3 for RIA applications generally or with the .NET RIA Services preview)?</p>
<p>In the meantime, if you’d like to play with my prototype/source, you can find it below.&#160; This code is provided under the <a href="http://www.microsoft.com/opensource/licenses.mspx#Ms-PL">Microsoft Public License</a> and is also provided &quot;as is&quot;, without warranty of any kind.</p>
<ul>
<li><a href="http://www.davidpoll.com/samples/download/ActivityControl.zip">Activity Control</a> (built on SL3 beta 1) </li>
<li><a href="http://www.davidpoll.com/samples/download/ActivitySample.zip">Activity control demo project, shown above</a> (requires SL3 beta 1 and .NET RIA Services) </li>
</ul>
<p>Enjoy!</p>
<p>&#160;</p>
<p><strong><em>Update 6/11/2009 – </em></strong>A new version of the control is available <a href="http://www.davidpoll.com/?p=73" target="_blank">here</a>.</p>
<p><strong><em>Update 7/11/2009 – </em></strong>Samples updated for Silverlight 3!</p>
<p><strong><em>Update 9/14/2009 – </em></strong>I’ve made a small update to the Activity control to fix a performance issue.&#160; You can find it <a href="http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/">here</a>.</p>
<p>P.S. Thanks to <a href="http://blogs.msdn.com/corrinab/">CorrinaB</a> for helping me snazz up the UI!</p>
<p><img alt="" src="http://blogs.msdn.com/aggbug.aspx?PostID=9491183" width="1" height="1" /></p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
	</channel>
</rss>

