Silverlight Help Silverlight Help http://www.silverlight-help.com/Tips.aspx http://backend.userland.com/rss OpenID User Control in Silverlight &ndash; Part 1 UI Design <p><img style="margin: 0px 15px 0px 0px; display: inline" align="left" src="http://openid.net/images/logo/openid-icon-100x100.png" />More and more I see sites supporting <a href="http://openid.net/" target="_blank">OpenID</a> as Authentication mechanism. I’m for example a user of sites like: <a href="http://ineedtoreadthis.com/" target="_blank">I need to read this</a>, <a href="http://getsatisfaction.com/" target="_blank">Get Satisfaction</a> and Google Login more or less.</p> <p>To support my own family I set up OpenID on my own domain, <a href="http://openid.mymonster.nl/">http://openid.mymonster.nl/</a> hosted by <a href="https://www.myopenid.com/" target="_blank">MyOpenID</a>. This just works like a charm. For the purpose of this article I created a test identity at my MyOpenID. I suggest everyone doing development for openid connectivity to create a test identity, I don’t want to mess with my real OpenID identity. This is part one of a three part series on the creation of an OpenID User Control. I initially created the control for use in my own application and have submitted it to the <a href="http://gosilverlight.org/ContestEntries" target="_blank">Silverlight Control Builder Contest of 2009</a>.</p> <p><strong>UI Design</strong></p> <p>One of the first things I was thinking about, was my design capacities. I came up with the following design, before signing in.</p> <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="OpenID User Control before signing in" border="0" alt="OpenID User Control before signing in" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-OpenIDUserControlinSilverlight_130BE-image_6.sflb.ashx" width="336" height="56" /> </p> <p>After you have signed in.</p> <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="OpenID User Control after signing in" border="0" alt="OpenID User Control after signing in" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-OpenIDUserControlinSilverlight_130BE-image_5.sflb.ashx" width="334" height="56" /> </p> <p>Yes I know, it’s very straightforward, and all the designers in this world could have thought about a better alternative. That’s why I thought this control to require the ability to template it. There are some articles on the web about templating Silverlight User Controls, <a href="http://msdn.microsoft.com/en-us/magazine/cc721611.aspx" target="_blank">this one helped me</a> a lot.</p> <p>To support Templating for a user control it needs to inherit ContentControl</p> <p>Visually I identified two states:</p> <p>- Unauthenticated – This state is active when the user hasn’t signed in yet.</p> <p>- Authenticated – This state is active when the user has successfully signed in.</p> <p>If the sign in was successful the control will move to the authenticated state. These Visual States can be used in the Xaml part of the user control, which we will do later on.</p> <p>As you can see in the above pictures we can think about three essential parts in this control.</p> <p>- LoginButton, typeof(Button)</p> <p>- IdentityInput, typeof(TextBox)</p> <p>- IdentitySuccessLabel, typeof(TextBlock)</p> <p>When you combine just these parts the C# file will look like this. (Please note, some parts are left out for the clear picture).</p> <p>&#160;</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:9ad98ce2-f212-49b9-9ebd-1d3e07cd1e48" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">[TemplatePart(Name = LoginButton, Type = typeof(Button))] [TemplatePart(Name = IdentityInput, Type = typeof(TextBox))] [TemplatePart(Name = IdentitySuccessLabel, Type = typeof(TextBlock))] [TemplateVisualState(Name = VisualStates.Unauthenticated, GroupName = VisualStates.CommonStates)] [TemplateVisualState(Name = VisualStates.Authenticated, GroupName = VisualStates.CommonStates)] public class OpenIdLoginControl : ContentControl { private const string IdentityInput = &quot;IdentityInput&quot;; private const string IdentitySuccessLabel = &quot;IdentitySuccessLabel&quot;; private const string LoginButton = &quot;LoginButton&quot;; private TextBox m_identityInput; private TextBlock m_identitySuccessLabel; private Button m_loginButton; public OpenIdLoginControl() { DefaultStyleKey = typeof(OpenIdLoginControl); } public override void OnApplyTemplate() { base.OnApplyTemplate(); m_identityInput = (TextBox)GetTemplateChild(IdentityInput); m_loginButton = (Button)GetTemplateChild(LoginButton); m_identitySuccessLabel = (TextBlock)GetTemplateChild(IdentitySuccessLabel); } #region Nested type: VisualStates private static class VisualStates { internal const string Authenticated = &quot;Authenticated&quot;; internal const string CommonStates = &quot;CommonStates&quot;; internal const string Unauthenticated = &quot;Unauthenticated&quot;; } #endregion }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>&#160;</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-OpenIDUserControlinSilverlight_130BE-image_8.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-OpenIDUserControlinSilverlight_130BE-image_thumb_2.sflb.ashx" width="163" height="84" /></a> To give this control a default style there needs to be a <strong>Themes</strong> directory and a xaml-file called <strong>Generic.xaml</strong> inside the library which will contain this control. The Generic.xaml file is a ResourceDictionary, and in this case we add a style for the OpenIdLoginControl. The xaml file kind of looks like the following (I removed the VisualStateManager parts for the VisualStates).</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:b588353c-d674-44b9-8925-05d122af3466" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">&lt;ResourceDictionary xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; xmlns:vsm=&quot;clr-namespace:System.Windows;assembly=System.Windows&quot; xmlns:openid=&quot;clr-namespace:MM.OpenId.Controls&quot;&gt; &lt;Style TargetType=&quot;openid:OpenIdLoginControl&quot;&gt; &lt;Setter Property=&quot;Width&quot; Value=&quot;330&quot; /&gt; &lt;Setter Property=&quot;Height&quot; Value=&quot;50&quot; /&gt; &lt;Setter Property=&quot;Template&quot;&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType=&quot;openid:OpenIdLoginControl&quot;&gt; &lt;Border BorderBrush=&quot;Black&quot; CornerRadius=&quot;4&quot; BorderThickness=&quot;1&quot;&gt; &lt;Grid x:Name=&quot;LayoutRoot&quot; Width=&quot;{TemplateBinding Width}&quot; Height=&quot;{TemplateBinding Height}&quot;&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition /&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width=&quot;auto&quot; /&gt; &lt;ColumnDefinition Width=&quot;*&quot;/&gt; &lt;ColumnDefinition Width=&quot;auto&quot;/&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;Image Grid.Column=&quot;0&quot; Grid.Row=&quot;0&quot; Source=&quot;/MM.OpenId.Controls;component/openid-icon.png&quot; Width=&quot;30&quot; Height=&quot;30&quot; Margin=&quot;8&quot;/&gt; &lt;TextBlock Grid.Column=&quot;1&quot; Grid.Row=&quot;0&quot; x:Name=&quot;IdentitySuccessLabel&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;8&quot; HorizontalAlignment=&quot;Center&quot; /&gt; &lt;TextBox Grid.Column=&quot;1&quot; Grid.Row=&quot;0&quot; x:Name=&quot;IdentityInput&quot; Text=&quot;http://openid.mymonster.nl/demo&quot; HorizontalAlignment=&quot;Stretch&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;8&quot; /&gt; &lt;Button Grid.Column=&quot;2&quot; Grid.Row=&quot;0&quot; x:Name=&quot;LoginButton&quot; Content=&quot;Sign In&quot; Margin=&quot;8&quot; /&gt; &lt;/Grid&gt; &lt;/Border&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; &lt;/ResourceDictionary&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Because this is just the default template, you can change this to adjust it to your own application.</p> <p>Because the extreme size of this article I’ve split this article into multiple articles. I will provide the full source at the end of the last article. You can expect at least the following two parts:</p> <p>- OpenID Integration</p> <p>- Integration in your own application</p> <em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em> http://www.silverlight-help.com/Tips/09-07-28/OpenID_User_Control_in_Silverlight_ndash_Part_1_UI_Design.aspx Mark Monster http://www.silverlight-help.com/Tips/09-07-28/OpenID_User_Control_in_Silverlight_ndash_Part_1_UI_Design.aspx b59f8c96-5dea-46fd-bdfd-e348768e51a5 Tue, 28 Jul 2009 14:05:22 GMT Silverlight 3 Could Not download the silverlight Application <p>I created a simple Silverlight 3 app.</p> <p>&#160;</p> <p>&lt;UserControl x:Class=&quot;SilverlightApplication2.MainPage&quot; <br />&#160;&#160;&#160; xmlns=&quot;<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;">http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</a> <br />&#160;&#160;&#160; xmlns:x=&quot;<a href="http://schemas.microsoft.com/winfx/2006/xaml&quot;">http://schemas.microsoft.com/winfx/2006/xaml&quot;</a> <br />&#160;&#160;&#160; xmlns:d=&quot;<a href="http://schemas.microsoft.com/expression/blend/2008&quot;">http://schemas.microsoft.com/expression/blend/2008&quot;</a> xmlns:mc=&quot;<a href="http://schemas.openxmlformats.org/markup-compatibility/2006&quot;">http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</a> <br />&#160;&#160;&#160; mc:Ignorable=&quot;d&quot; d:DesignWidth=&quot;640&quot; d:DesignHeight=&quot;480&quot;&gt; <br />&#160;&#160;&#160; &lt;Grid x:Name=&quot;LayoutRoot&quot;&gt; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;TextBlock Text=&quot;Hello World!&quot; &gt;&lt;/TextBlock&gt; <br />&#160;&#160;&#160; &lt;/Grid&gt; <br />&lt;/UserControl&gt;</p> <p>&#160;</p> <p>When I run it I get this error</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3CouldNotdownloadthesilverlig_5FF5-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3CouldNotdownloadthesilverlig_5FF5-image_thumb.sflb.ashx" width="244" height="163" /></a> </p> <p>Line: 56 <br />Error: Unhandled Error in Silverlight Application <br />Code: 2104&#160;&#160;&#160; <br />Category: InitializeError&#160;&#160;&#160;&#160;&#160;&#160; <br />Message: Could not download the Silverlight application. Check web server settings&#160;&#160;&#160; </p> <p>&#160;</p> <p>Well if you look in the ClientBin folder you will see it is empty so the xap file is not available to be used</p> <p>&#160;</p> <p>To fix this right click on the web application and select Build Order.&#160; On the Dependencies tab make sure the Checkbox next to the Silverlight app is checked.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3CouldNotdownloadthesilverlig_5FF5-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3CouldNotdownloadthesilverlig_5FF5-image_thumb_1.sflb.ashx" width="244" height="233" /></a></p> http://www.silverlight-help.com/Tips/09-07-15/Silverlight_3_Could_Not_download_the_silverlight_Application.aspx Ken Tucker http://www.silverlight-help.com/Tips/09-07-15/Silverlight_3_Could_Not_download_the_silverlight_Application.aspx a57cd687-20d8-4584-947a-209084eda88c Wed, 15 Jul 2009 05:47:15 GMT Tracking Silverlight (1, 2 and 3) support in Google Analytics <p>Half a year ago I blogged about <a href="http://mark.mymonster.nl/2009/02/15/tracking-silverlight-support-in-google-analytics/" target="_blank">tracking Silverlight support in Google Analytics</a>. I’ve had a lot of reactions on how to track Silverlight support. In my original article I made use of virtual page views to track Silverlight support. But there are different options available to track Silverlight support.</p> <p><strong></strong></p> <p><strong>Tracking through Virtual Page Views</strong></p> <p>When you make use of Virtual Page Views to track Silverlight support you will get inconsistencies in your Page Views. You will get twice as much Page Views as there really are, not the best solution I think.</p> <p><strong></strong></p> <p><strong>Tracking through Events</strong></p> <p>We can also track information in Google Analytics using Events. But it’s difficult to associate this information directly to the amount of visitors. I think using Events for tracking Silverlight support is the second best option we have.</p> <p><strong></strong></p> <p><strong>Tracking through User Defined Value</strong></p> <p>We can also track information using the User Defined Value. This value is directly associated to the visitor. So even if your visitor takes a look at 10 pages, it will only track this value once. But the difficult thing with Google Analytics is the amount of User Defined Values we can have. It’s exactly <strong>one</strong>. So if you’re already using this User Defined Value for an other purpose, you will have to take advantage of the other options, like Event Tracking or Virtual Page View Tracking.</p> <p>My preferred way of Tracking Silverlight support is using User Defined Values. If you’re already using the User Defined Value, your best option for tracking is Events.</p> <p><strong></strong></p> <p><strong>Implementing tracking using the User Defined Value</strong></p> <p>First of all, you’ll need the <a href="http://code.msdn.microsoft.com/silverlightjs" target="_blank">Silverlight.js file from MSDN Code</a>. This file hasn’t changed for the release of Silverlight 3, so if you’ve already got this file, you don’t have to update it.</p> <p>Reference Silverlight.js:</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:106885f5-c909-487a-ad68-7fe83460826d" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">&lt;script type=&quot;text/javascript&quot; src=&quot;**/Silverlight.js&quot;&gt;&lt;/script&gt; </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>You probably already have the Javascript code for Referencing Google Analytics, it’s like this.</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:b7227081-a7f4-48a7-8085-2fcffe466ede" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">&lt;script type=&quot;text/javascript&quot;&gt; var gaJsHost = ((&quot;https:&quot; == document.location.protocol) ? &quot;https://ssl.&quot; : &quot;http://www.&quot;); document.write(unescape(&quot;%3Cscript src='&quot; + gaJsHost + &quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&quot;)); &lt;/script&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Let’s write a Javascript function to return the current Silverlight version. Although there’s backwards compatibility I only want to know the highest version supported.</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:192b7c3a-6a94-4da2-8145-5489438f3caa" class="wlWriterEditableSmartContent"><pre class="brush: jscript; gutter: true; first-line: 1; tab-size: 2; toolbar: false; highlight: 19 ;">function getSilverlightVersion() { var version = ''; var container = null; try { var control = null; if (window.ActiveXObject) { control = new ActiveXObject('AgControl.AgControl'); } else { if (navigator.plugins['Silverlight Plug-In']) { container = document.createElement('div'); document.body.appendChild(container); container.innerHTML= '&lt;embed type=&quot;application/x-silverlight&quot; src=&quot;data:,&quot; /&gt;'; control = container.childNodes[0]; } } if (control) { if (control.isVersionSupported('3.0')) { version = 'Silverlight/3.0'; } else if (control.isVersionSupported('2.0')) { version = 'Silverlight/2.0'; } else if (control.isVersionSupported('1.0')) { version = 'Silverlight/1.0'; } } } catch (e) { } if (container) { document.body.removeChild(container); } return version; } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Let’s combine this function with the tracking of the value returned in the User Defined Value.</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:3b854d2a-90f4-479f-b23e-b0780226cf6f" class="wlWriterEditableSmartContent"><pre class="brush: jscript; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">var pageTracker = _gat._getTracker(&quot;UA-xxxx-x&quot;); $(function() { pageTracker._trackPageview(); var version = getSilverlightVersion(); if (version) { pageTracker._setVar(version); } });</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Because I’m using JQuery on my homepage as well, I put this tracking in the ready of page loading. </p> <p>&#160;</p> <p><strong>What does it look like in Google Analytics?</strong></p> <p>Let’s take a look at the statistics for my website containing the User Defined Value since I added support for Silverlight 3 tracking. It’s interesting to see that already a lot of people are using Silverlight 3.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-TrackingSilverlight12and3supportinGoogle_1322A-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Silverlight usage stats" border="0" alt="Silverlight usage stats" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-TrackingSilverlight12and3supportinGoogle_1322A-image_thumb.sflb.ashx" width="669" height="320" /></a> </p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-07-12/Tracking_Silverlight_1_2_and_3_support_in_Google_Analytics.aspx Mark Monster http://www.silverlight-help.com/Tips/09-07-12/Tracking_Silverlight_1_2_and_3_support_in_Google_Analytics.aspx e24068c1-e46f-4165-8c60-6977aa3249e2 Sun, 12 Jul 2009 12:55:53 GMT Silverlight 3 &ndash; Did we get support for Credentials? <p>A few months ago, <a href="http://mark.mymonster.nl/2009/03/22/silverlight-3-webclient-webrequest-and-wcf-calls-using-credentials/" target="_blank">I investigated Silverlight 3 Beta on support for Credentials</a>.</p> <p>There are two classes that give a little bit of notion that they are supporting Credentials. Both <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient_properties(VS.95).aspx" target="_blank"><strong>WebClient</strong></a> and <strong><a href="http://msdn.microsoft.com/en-us/library/system.net.webrequest_properties(VS.95).aspx" target="_blank">WebRequest</a></strong> have a property <strong>Credentials</strong> of type <strong>ICredentials</strong>. Let’s try them one by one.</p> <p><strong>WebRequest credentials support?</strong></p> <p>First we need to have some code to request the content behind an url and assign a set of credentials to the request.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:f60e1e57-953d-4323-ada3-a89c6b9894b5" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">WebRequest request = HttpWebRequest.Create(&quot;http://mark.mymonster.nl&quot;); request.Credentials = new NetworkCredential(&quot;username&quot;, &quot;password&quot;);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Very straightforward code which you can write for the full CLR as well. This code doesn’t even contain the execution of the request.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NotImplementedException when using Credentials on WebRequest" border="0" alt="NotImplementedException when using Credentials on WebRequest" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_thumb.sflb.ashx" width="644" height="171" /></a> </p> <p>Yes it fails. If you try to set the de Credentials you will get a <strong>NotImplementedException</strong>. Sad, so we have not support for credentials in the WebRequest.</p> <p><em>WebRequest credentials support outcome: <strong>Negative</strong></em></p> <p><strong>WebClient credentials support?</strong></p> <p>Next class with a Credentials property, WebClient. First let’s write some code.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:4aa63dab-60b4-45c9-a7b8-fdd3f7d6b3a5" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">var client = new WebClient { Credentials = new NetworkCredential(&quot;username&quot;, &quot;password&quot;) }; client.DownloadStringCompleted += client_DownloadStringCompleted; client.DownloadStringAsync(new Uri(&quot;http://mark.mymonster.nl&quot;)); </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Of course if anything goes wrong we can see it in the DownloadStringCompleted. From QuickWatch, we can see what happened.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NotImplementedException when using Credentials on WebClient" border="0" alt="NotImplementedException when using Credentials on WebClient" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_thumb_1.sflb.ashx" width="644" height="206" /></a> </p> <p>Hmm, I could have guessed that WebClient internally makes use of WebRequest. So also WebClient doesn’t support credentials. </p> <p>WebClient credentials support outcome: <strong>Negative</strong></p> <p><strong>Hmm, last option we have: Adding the Authorization header manually</strong></p> <p>In the past I also tried to <a href="http://mark.mymonster.nl/2008/07/12/silverlight-networking-getting-credentials-to-work-unsuccessful/" target="_blank">add the Authorization header manually</a>. I won’t go into the details but, the implementation of the Credentials property would mean that some data would be put into the Authorization header.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_6.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ArgumentException when trying to apply an Authorization Header" border="0" alt="ArgumentException when trying to apply an Authorization Header" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3DidwegetsupportforCredential_CDA8-image_thumb_2.sflb.ashx" width="644" height="180" /></a> </p> <p>Sad, this still doesn’t work. The ‘Authorization’ header cannot be modified directly.</p> <p><em>Manually adding Authorization header outcome: <strong>Negative</strong></em></p> <p><strong>Conclusion</strong></p> <p>Sadly both WebClient and WebRequest don’t support Credentials yet. I would have thought it did support, basically because they supplied a property called Credentials that wasn’t in the Silverlight 2 release. I’m just wondering if they just didn’t get the implementation in place on time for the RTW of Silverlight 3.</p> <p>Trying to do it manually isn’t supported as well. I’m just wondering why do we have a property Credentials on those objects? Would be nice to get some response from the Silverlight team on this one.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-07-11/Silverlight_3_ndash_Did_we_get_support_for_Credentials.aspx Mark Monster http://www.silverlight-help.com/Tips/09-07-11/Silverlight_3_ndash_Did_we_get_support_for_Credentials.aspx 2ebaeca0-6b98-44e3-8d7b-cd9cb9aa89a1 Sat, 11 Jul 2009 13:22:19 GMT Silverlight 3 talking to a RIA Service, everything hosted on Windows Azure <p>This is my first tryout of Windows Azure. I wanted to know if it’s possible to run the Preview of RIA Service on the CTP of Windows Azure.</p> <p>First of all you’ll need a lot of different components, and if you want to host your solution in the cloud you’ll also need to register at Windows Azure.</p> <p>- Register first: <a href="http://www.microsoft.com/azure/register.mspx">http://www.microsoft.com/azure/register.mspx</a></p> <p>I assume you’ve already a machine running Visual Studio 2008 SP1. But even then you’ll need to download and install the following components if you haven’t done yet.</p> <p>- Silverlight 3 Beta Tools for Visual Studio: <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=11dc7151-dbd6-4e39-878f-5081863cbb5d&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?FamilyId=11dc7151-dbd6-4e39-878f-5081863cbb5d&amp;displaylang=en</a></p> <p>- .NET RIA Service May 2009 Preview: <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en</a></p> <p>- Windows Azure Tools for Visual Studio May 2009 CTP: <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=11b451c4-7a7b-4537-a769-e1d157bad8c6&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=11b451c4-7a7b-4537-a769-e1d157bad8c6&amp;displaylang=en</a></p> <p>&#160;</p> <p><strong>Everything installed? Let’s start with the general setup</strong></p> <p>I first created an empty Solution, I always do this, because this is the only to have complete control over the naming. After that I added a Web Cloud Service, just like the screen below.</p> <a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add a Web Cloud Service" border="0" alt="Add a Web Cloud Service" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_1.sflb.ashx" width="644" height="416" /></a> <p>My solution still basic, no coding done yet, looks like this:</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_6.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Solution view with Web Project and Web Cloud Project" border="0" alt="Solution view with Web Project and Web Cloud Project" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_2.sflb.ashx" width="244" height="198" /></a> </p> <p>Add a Silverlight Application project, and ensure that this Silverlight Application is hosted in the Webproject created in the previous step. Normally we would create a Silverlight Business Application, but we are going to associate RIA manually to this Silverlight Application.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_8.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="New Silverlight application dialog" border="0" alt="New Silverlight application dialog" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_3.sflb.ashx" width="443" height="417" /></a></p> <p>Let’s add a reference to the RIA library that’s needed to run this solution. You can find this library in: <strong><em>C:\Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\</em></strong> (of course this can be different, depending on your installation location).</p> <p>- System.Windows.RIA</p> <p>There’s also a different library containing User Interface parts, we aren’t using it in this example but this is:</p> <p>- System.Windows.Ria.Controls</p> <p><strong></strong></p> <p><strong>Enable RIA on this Web Project</strong></p> <p>Before we start our coding, let’s configure the web project to enable RIA Services. I’ve <a href="http://mark.mymonster.nl/2009/04/05/silverlight-3-and-ria-services-the-basics/">explained it before</a>, but for Windows Azure it’s a little bit different.</p> <p>Add references to the following dll’s:</p> <p>- System.ComponentModel.DataAnnotations</p> <p>- System.Web.DomainServices </p> <p>- System.Web.Ria</p> <p>We still need to add the Http Handler for RIA Services. In my previous explanation I only explained how to do this for older versions of IIS. But Windows Azure is running on IIS 7. So the handler needs to be added to the <strong>handlers</strong> section in the <strong>system.webserver</strong> element.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:13c95b1c-828c-43b1-938b-99e4faac6cc6" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">&lt;add name=&quot;DataService&quot; verb=&quot;GET,POST&quot; path=&quot;DataService.axd&quot; type=&quot;System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; /&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>&#160;</p> <p><strong>Enable RIA on the Web Cloud Project</strong></p> <p>To enable RIA on the Web Cloud Project you have to change the <strong>ServiceDefinition.csdef</strong> file. Set the <strong>enableNativeCodeExecution</strong> to <strong>true</strong>.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:4ba06a6f-89f8-4a37-9013-c5aef3263d9d" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;ServiceDefinition name=&quot;MM.SilverToGold.Web.Cloud&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt; &lt;WebRole name=&quot;WebRole&quot; enableNativeCodeExecution=&quot;true&quot;&gt; &lt;InputEndpoints&gt; &lt;!-- Must use port 80 for http and port 443 for https when running in the cloud --&gt; &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;http&quot; port=&quot;80&quot; /&gt; &lt;/InputEndpoints&gt; &lt;/WebRole&gt; &lt;/ServiceDefinition&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>&#160;</p> <p><strong>Coding</strong></p> <p>Now it’s time for coding, though I won’t explain much about the code. Please read <a href="http://mark.mymonster.nl/tag/ria-services/" target="_blank">my other RIA articles</a> to get coding for RIA Service in your fingers.</p> <p>First the RIA Service part, a very simple <strong>HelloWorldDomainService</strong>, just add the following class to your Web project.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:bda8a7ca-9fc3-4539-a423-33c4b55d76f3" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">using System.Web.DomainServices; using System.Web.Ria; namespace MM.HelloWorld.Web { [EnableClientAccess] public class HelloWorldDomainService : DomainService { [ServiceOperation] public string HelloWorld(string name) { return string.Format(&quot;Hello {0}, from RIA Services running in the Cloud.&quot;, name); } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>When you now build the solution the Silverlight part will get generated.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_10.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Show the RIA Services generated file" border="0" alt="Show the RIA Services generated file" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb.sflb.ashx" width="288" height="335" /></a>&#160; </p> <p><strong>Coding the Silverlight part</strong></p> <p>We now have completed the RIA Services part, let’s do the Silverlight coding. First some UI, containing a button, a input field and a result field. I also added a Click event to the button.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:f3a3faa9-fbbc-4c42-ab86-5f119111d57e" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">&lt;UserControl x:Class=&quot;MM.HelloWorld.Sui.MainPage&quot; xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; Width=&quot;400&quot; Height=&quot;300&quot;&gt; &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt; &lt;StackPanel&gt; &lt;StackPanel Height=&quot;45&quot; Width=&quot;Auto&quot; Orientation=&quot;Horizontal&quot;&gt; &lt;TextBlock FontSize=&quot;20&quot; VerticalAlignment=&quot;Center&quot; Width=&quot;201&quot; Text=&quot;What's your name:&quot;/&gt; &lt;TextBox x:Name=&quot;NameTextBox&quot; Height=&quot;25&quot; Width=&quot;192&quot; Background=&quot;#FFFFFFFF&quot; BorderThickness=&quot;2,2,2,2&quot; FontSize=&quot;14&quot;/&gt; &lt;/StackPanel&gt; &lt;Button Content=&quot;Hello?&quot; Click=&quot;Button_Click&quot; Height=&quot;33&quot; FontSize=&quot;20&quot; Margin=&quot;5,5,5,5&quot;/&gt; &lt;TextBlock x:Name=&quot;WorldResponse&quot;/&gt; &lt;/StackPanel&gt; &lt;/Grid&gt; &lt;/UserControl&gt; </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Alright, in the Click event we want to call the RIA Service, and let’s hope the RIA Service running in the cloud answers us.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:84f756d6-ebed-4802-8814-9e9827a90d29" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">private void Button_Click(object sender, RoutedEventArgs e) { var helloWorldDomainContext = new HelloWorldDomainContext(); helloWorldDomainContext.HelloWorldCompleted += HelloWorldDomainContextHelloWorldCompleted; helloWorldDomainContext.HelloWorld(NameTextBox.Text); }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>The code for the HelloWorldCompleted event is very simple, it’s just setting the text of a TextBlock. Please note the event automatically <a href="http://mark.mymonster.nl/2008/07/12/silverlight-threading-getting-back-to-the-ui-thread/" target="_blank">get’s you back to the UI-Thread</a>, no manually checking for UI-Thread required.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:ede37643-5e1b-4d7e-8157-ff122a4e0883" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: false; ">private void HelloWorldDomainContextHelloWorldCompleted(object sender, InvokeEventArgs e) { if(e.ReturnValue!=null) WorldResponse.Text = e.ReturnValue.ToString(); }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>When you test this locally, it will run, but the interesting part of course: Will it run on Windows Azure?</p> <p><strong></strong></p> <p><strong>Let it run on Windows Azure</strong></p> <p>To get your solution to Windows Azure you will first have to right-click the cloud-project, and choose for Publish. This will open a Windows Explorer window showing the files that are ready for publishing. In this example it looks like this.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_12.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_4.sflb.ashx" width="161" height="42" /></a> </p> <p>We’ll now <a href="http://lx.azure.microsoft.com/fs" target="_blank">logon to the Windows Azure portal</a>. In here you have to create a Hosted Services project. I’ve already done this before, but there are articles on the web about creating a Hosted Services project on Windows Azure. To be honest, you can even do this without an article. My portal looks like this.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_14.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows Azure Developer Portal" border="0" alt="Windows Azure Developer Portal" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_5.sflb.ashx" width="644" height="361" /></a> </p> <p>Let’s choose the Hosted Services project, this project is called “Monster Cloud” in my Azure environment. But you can have your own name. The next page looks like this.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_16.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows Azure Developer Portal - Hosted Services project" border="0" alt="Windows Azure Developer Portal - Hosted Services project" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_6.sflb.ashx" width="644" height="393" /></a> </p> <p>Let’s click the Deploy button, and see what happens.</p> <a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_18.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows Azure Developer Portal - Deploy a new package screen" border="0" alt="Windows Azure Developer Portal - Deploy a new package screen" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_7.sflb.ashx" width="644" height="444" /></a> <p>Ah we need to provide a few things. An application package, we have this already, it’s in our publish folder that was created for us: MM.HelloWorld.Web.Cloud.cspkg.</p> <p>Let’s browse for this file, and also pick the Configuration Settings file, this is: ServiceConfiguration.cscfg.</p> <p>All that’s left is providing a label name, and clicking the Deploy button. My screen looked like this before clicking Deploy.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_20.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows Azure Developer Portal - Deploy a new package screen, filled" border="0" alt="Windows Azure Developer Portal - Deploy a new package screen, filled" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_8.sflb.ashx" width="644" height="442" /></a> </p> <p>When clicking deploy a lot of things are being done behind the scenes. First of all the files are uploaded, but also a kind of VM get’s created for us, this takes some time, might even take 5 minutes or longer. So you definitely have to have a bit of patience. After the deployment was complete my screen looked like this. </p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_22.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows Azure Developer Portal - Run the Azure package" border="0" alt="Windows Azure Developer Portal - Run the Azure package" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_9.sflb.ashx" width="644" height="424" /></a> </p> <p>Let’s click the Run button.</p> <p>So let’s try the url that’s created for our staging environment. For a brief period of time, you can <a href="http://b59f5e463c364748a29be3cbc4757202.cloudapp.net/MM.HelloWorld.SuiTestPage.html" target="_blank">take a look at my staging environment</a>.</p> <p>It’s working as expected. We now have a Silverlight 3 application communicating with RIA Services, and everything running in the cloud.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_24.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Testing the Silverlight 3 communicating with RIA Services, all running on the cloud." border="0" alt="Testing the Silverlight 3 communicating with RIA Services, all running on the cloud." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3talkingtoaRIAServiceeverythi_135D4-image_thumb_10.sflb.ashx" width="597" height="216" /></a> </p> <p>You can <a href="http://mark.mymonster.nl/wp-content/uploads/2009/07/mmhelloworldsolution.zip" target="_blank">download the Source Files</a>. If you have any questions or remarks please let me know.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-07-05/Silverlight_3_talking_to_a_RIA_Service_everything_hosted_on_Windows_Azure.aspx Mark Monster http://www.silverlight-help.com/Tips/09-07-05/Silverlight_3_talking_to_a_RIA_Service_everything_hosted_on_Windows_Azure.aspx 79307bdb-4db7-4a69-a3fc-5f5f622713f4 Sun, 05 Jul 2009 03:25:24 GMT John Papa speaking at Space Coast .Net <h5><a _tesavedurl="http://www.scdnug.org/#" href="http://www.scdnug.org/#">John Papa - Ado.Net Data Services</a></h5> <p>6/17/2009 6:30:00 PM </p> <p>6/17/2009 8:00:00 PM </p> <h3>About</h3> <p><a _tesavedurl="http://johnpapa.net/files/media/image/WindowsLiveWriter/About_AF62/jp2_2.jpg" href="http://johnpapa.net/files/media/image/WindowsLiveWriter/About_AF62/jp2_2.jpg"><img height="133" width="100" _tesavedurl="http://johnpapa.net/files/media/image/WindowsLiveWriter/About_AF62/jp2_thumb.jpg" src="http://johnpapa.net/files/media/image/WindowsLiveWriter/About_AF62/jp2_thumb.jpg" alt="jp2" title="jp2" /></a> </p> <p>John Papa is a <a _tesavedurl="https://mvp.support.microsoft.com/profile=7D3BBCB7-E956-4730-B3E0-24BD7EAD0D5D" href="https://mvp.support.microsoft.com/profile=7D3BBCB7-E956-4730-B3E0-24BD7EAD0D5D">Microsoft C# MVP</a>, <a _tesavedurl="http://www.ineta.org/DesktopDefault.aspx?tabindex=2&amp;tabid=14" href="http://www.ineta.org/DesktopDefault.aspx?tabindex=2&amp;tabid=14">INETA speaker</a>, member of the WPF and Silverlight Insiders, consultant, speaker, author, and trainer for <a _tesavedurl="http://www.aspsoft.com/" href="http://www.aspsoft.com/">ASPSOFT</a> who specializes in professional application development with Microsoft technologies including Silverlight, WPF, C#, .NET and SQL Server. John has written over 70 articles and authored 9 books including his latest book <a _tesavedurl="http://www.amazon.com/exec/obidos/ASIN/0596523092/johnpanet-20" href="http://www.amazon.com/exec/obidos/ASIN/0596523092/johnpanet-20">Data Driven Services with Silverlight 2</a> by O’Reilly Media. John is currently working on a follow up to his Silverlight book, with a working title of Silverlight for Business. </p> <p>He can often be found speaking at industry conferences such as <a _tesavedurl="http://www.visitmix.com/" href="http://www.visitmix.com/">MIX</a>,&nbsp; <a _tesavedurl="http://www.vslive.com/" href="http://www.vslive.com/">VSLive</a> and <a _tesavedurl="http://www.devconnections.com/" href="http://www.devconnections.com/">DevConnections</a>, speaking at user groups around the country, and viewed on MSDN Web Casts. John also spearheaded the 1<sup>st</sup> annual Silverlight MIXer, a gathering of some of the most influential members of the Silverlight community for a great night a MIX09. You can always find John at <a _tesavedurl="http://www.johnpapa.net/" href="http://www.johnpapa.net/">johnpapa.net</a>. </p> <p>John Papa will be showing Astoria using Silverlight 3 beta as the client. </p> <p>ADO.NET Data Services (codenamed Astoria) exposes entity models through RESTful services. It can dramatically simplify the code required to expose business objects through web services and reduce a tremendous amount of code. This session will show how to expose entity models using ADO.NET Data Services, how to consume and save data, and how to debug the communications using various tools. When the technology does not quite do what you need out of the box, it also allows for customizations to create custom service operations, intercept queries, and enforce permissions. Attendees will walk away with an understanding of the capabilities of ADO.NET Data Services, how to use them with Silverlight, and when and where it is ideal to use in an application architecture and when there are better options. </p> <p>Street: 8045 N. Wickham Road <br /> City: melbourne<br /> Country: USA<br /> State: Florida </p> http://www.silverlight-help.com/Tips/09-06-15/John_Papa_speaking_at_Space_Coast_Net.aspx Ken Tucker http://www.silverlight-help.com/Tips/09-06-15/John_Papa_speaking_at_Space_Coast_Net.aspx abd427d3-d35e-4afd-b731-aaabb02914ae Mon, 15 Jun 2009 11:56:00 GMT Moonlight 2 Preview 4, testing differently <p>I read we now have a new preview of the Moonlight runtime. It’s already the fourth preview. I’m giving a test run, just like I gave <a href="http://mark.mymonster.nl/2009/05/06/silverlight-on-linux-running-moonlight-20-preview-1/" target="_blank">preview 1</a> and <a href="http://mark.mymonster.nl/2009/05/20/moonlight-preview-3-a-new-test-run/" target="_blank">preview 3</a> a test run. But this time I did it differently. For the release notes <a href="http://www.mono-project.com/Moonlight/Preview#Preview_4" target="_blank">see this page</a>.</p> <p><strong>What size is the Moonlight runtime actually?</strong></p> <p>Currently it's about <strong>9 MiB</strong>, what does this mean? That’s this runtime is small as well. That this size is about <strong>50%</strong> higher than the <strong>Silverlight 3 beta</strong> release which has a size of about <strong>6 MiB</strong>.</p> <p><strong>Hunger for resources?</strong></p> <p>Something else I wanted to see is the resources it’s using. Let’s see what’s happening to the CPU usage when running the Silverlight Toolkit example page? If it keeps running of course. But as the screenshot shows the CPU usage of Firefox the parent process for Moonlight is consuming about 50% of the CPU. When running for a period it keeps consuming around 50% to 80% of the CPU.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Moonlight running the Silverlight Toolkit example page." border="0" alt="Moonlight running the Silverlight Toolkit example page." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_thumb_1.sflb.ashx" width="484" height="270" /></a> </p> <p>Let’s compare the same page to Silverlight, running in Chrome, you will have to search the correct process, because each Chrome Tab is running in it’s own process. But then again it’s still not consuming as much CPU as Moonlight is. It’s around 2% CPU usage.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Silverlight running the Silverlight Toolkit example page." border="0" alt="Silverlight running the Silverlight Toolkit example page." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_thumb.sflb.ashx" width="484" height="366" /></a> </p> <p>I would say, besides a lot of problems, the moonlight team definitely will have to work on the performance, because you can expect a little bit of difference in performance but this isn’t what I would expect.</p> <p><strong>Bugs?</strong></p> <p>In the last preview the Silverlight Toolkit wasn’t running the charts. It is running it now, isn’t it? Well, for a small period of time it was running, but while writing some parts of this post it stopped running.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_6.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_thumb_2.sflb.ashx" width="484" height="410" /></a> </p> <p>Is it running my own website? Of course for me is this very important because I now have a 3D-TagCloud running in Silverlight.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_8.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Moonlight2Preview4testingdifferently_1224F-image_thumb_3.sflb.ashx" width="484" height="388" /></a> </p> <p>It’s getting better, but still a lot of work. But I like the approach the Moonlight team has while developing the new Moonlight version. It’s more public, compared to Silverlight 3 which only got one beta, and I don’t expect more to arrive because the RTW of Silverlight 3 is announced to be on July 10th.</p> <p>Do you have Silverlight sites I need to test drive during the next test drive?</p> http://www.silverlight-help.com/Tips/09-06-07/Moonlight_2_Preview_4_testing_differently.aspx Mark Monster http://www.silverlight-help.com/Tips/09-06-07/Moonlight_2_Preview_4_testing_differently.aspx 4b6fb617-de45-400f-bfb6-a3d35c637f6a Sun, 07 Jun 2009 13:44:20 GMT Moonlight Preview 3, a new Test Run. <p>Moonlight has a new update. Basically I even missed the second preview. But here the test run of preview 3. The release notes are <a href="http://www.mono-project.com/Moonlight/Preview#Release_Notes" target="_blank">available here</a>.</p> <p>I just had to search for updates on my add-ons. Just updated it like any other Firefox add on. And a restart of the browser was all that was needed.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_thumb.sflb.ashx" width="484" height="376" /></a></p> <p>Just giving it the same new try as before.</p> <p>Of course I start with testing the Silverlight.net site. Does it still work? Yes it does, it even feels a little better. Faster response. But looks are the same, so no new screenshot.</p> <p>Next is <a href="http://silverlight.net/samples/sl2/toolkitcontrolsamples/run/default.html" target="_blank">the Silverlight Toolkit Example page for Silverlight 2</a>. Ah my first surprise. It runs, but let’s look at the charts, the browser stops responding.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_6.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_thumb_2.sflb.ashx" width="484" height="388" /></a> </p> <p>What about the <a href="http://silverlight.net/samples/sl3/toolkitcontrolsamples/run/default.html" target="_blank">Silverlight Toolkit examples for Silverlight 3</a>? Still crashes my dear browser.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_8.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_thumb_3.sflb.ashx" width="484" height="112" /></a> </p> <p>What about the performance of <a href="http://memorabilia.hardrock.com/" target="_blank">the Hard Rock deep-zoom site</a>? Yes it feels like it’s better, but I didn’t measure it. But while clicking around a little bit I got this screen and error.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_thumb_1.sflb.ashx" width="484" height="368" /></a>&#160;</p> <p>Hmm something else that is interesting to test is <a href="http://blogs.tamtam.nl/peterg/2009/02/13/CreatingA3DTagcloudInSilverlightPart1.aspx" target="_blank">the 3D Tag Cloud by Peter Gerritsen</a> will it run? And yes it runs! Interesting.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_10.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-MoonlightPreview3anewTestRun_1051D-image_thumb_4.sflb.ashx" width="484" height="388" /></a> </p> <p>Hmm, in the end it still not enough for pre-production. But it performs better, at least it feels like it.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-05-20/Moonlight_Preview_3_a_new_Test_Run.aspx Mark Monster http://www.silverlight-help.com/Tips/09-05-20/Moonlight_Preview_3_a_new_Test_Run.aspx be3ea01f-e704-4df5-8375-7f9b54cc9382 Wed, 20 May 2009 13:33:26 GMT Silverlight 3 and RIA Service &ndash; Cross Domain Proxy Enhanced <p>Some time ago I wrote <a href="http://mark.mymonster.nl/2009/04/09/silverlight-3-and-ria-service-creating-a-proxy-for-cross-domain-httprequests/">a very small RIA Service that could be used to overcome Cross Domain issues</a>. It’s a proxy that sits between your Silverlight application and any server where you want to get content over http.</p> <p>A lot people know that not even half of the public API’s have cross domain configurations in place. The best solution that’s left is a proxy that can forward the calls to the public API and return the response back to the original caller. This article will expand the Silverlight part of the Cross Domain Proxy. Nothing needs to be changed to the RIA Service part of this Cross Domain Proxy.</p> <p>What is the problem we have with the solution from my earlier article about Cross Domain Proxy?</p> <p>One thing: The Cross Domain Proxy RIA Service is a generic service that can be used for all cross domain accesses. So basically we could write an application that’s performing multiple calls through the cross domain proxy at the same time. But how do we use the responses? We basically have one event “ProcessCompleted”, should we then react to this event by doing different things? Yes that could be, but we could do it differently as well.</p> <p>I’m thinking about a ProxyService that’s running on Silverlight which has a little bit more knowledge compared to the RIA Services generated stub. This service would enable to do a cross domain request but provide a function to be called on completion at the same time.</p> <p>The code using this service would look like this (firing multiple cross domain requests at the same time):</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:7e5bd54d-7b53-4158-80a0-c49eecd03418" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">var domainProxyService = new DomainProxyService(); domainProxyService.Process( new ProxyRequest { Url = &quot;http://www.silverlight.net/&quot; }, response =&gt; Debug.WriteLine(string.Format(&quot;1:&quot;, response.Content))); domainProxyService.Process( new ProxyRequest { Url = &quot;http://www.asp.net/&quot; }, response =&gt; Debug.WriteLine(string.Format(&quot;2:&quot;, response.Content))); domainProxyService.Process( new ProxyRequest { Url = &quot;http://www.azure.net/&quot; }, response =&gt; Debug.WriteLine(string.Format(&quot;3:&quot;, response.Content)));</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>The DomainProxyService needs to be intelligent enough to be able to route the reponses to the correct function pointers.</p> <p>So there needs to be a key that can help associate the request with the response. In my last article I introduced the property <strong>Id</strong> in the <strong>ProxyRequest</strong> and the <strong>RequestId</strong> in the <strong>ProxyResponse</strong>. But for all purpose I don’t want to put a value in the Id, as a caller I don’t use this field, it’s just for internal usage so that association between Request and Response is possible.</p> <p>My idea is to put a dictionary in the DomainProxyService to associate the request id with a function pointer. I want the function point to be of a type void that accepts one parameter of type ProxyResponse. That would make a dictionary like this:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:712d32bc-21ff-4f01-95c8-1f9ded7864a2" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">private readonly Dictionary&lt;Guid, Action&lt;ProxyResponse&gt;&gt; m_dictionaryOfListeners = new Dictionary&lt;Guid, Action&lt;ProxyResponse&gt;&gt;();</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>The method to process a request isn’t that difficult. It will generate a new Id if it’s still empty. Besides that it will add an item to the dictionary, the key with the associated function to call on completion. And after all the most important part, we will call the original RIA Service.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:251ca5c2-90a1-4124-ba7f-b94696abfb2b" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">public void Process(ProxyRequest proxyRequest, Action&lt;ProxyResponse&gt; callBack) { //Generate a unique id if it doesn't contain an id yet. if (Guid.Empty == proxyRequest.Id) proxyRequest.Id = Guid.NewGuid(); //Add the callback to list of listeners for use on completion. m_dictionaryOfListeners.Add(proxyRequest.Id, callBack); m_domainProxy.Process(proxyRequest); } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>We will still need to have one generic listener for the ProcessCompleted event. This listener will look up the appropriate function to call in the dictionary. Will invoke the function and remove the item in the dictionary.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:958399b9-ef99-4537-9bc4-54989c15c3c6" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">private void DomainProxyProcessCompleted(object sender, InvokeEventArgs e) { var proxyResponse = e.ReturnValue as ProxyResponse; if (proxyResponse != null) { //If the dictionary contains listeners for this request if (m_dictionaryOfListeners.ContainsKey(proxyResponse.RequestId)) { m_dictionaryOfListeners[proxyResponse.RequestId].Invoke(proxyResponse); m_dictionaryOfListeners.Remove(proxyResponse.RequestId); } } } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>To be complete here the full source of the DomainProxyService class. Please remember this article continues on <a href="http://mark.mymonster.nl/2009/04/09/silverlight-3-and-ria-service-creating-a-proxy-for-cross-domain-httprequests/">my previous article about Domain Proxy</a>.</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:99d15de1-ac0d-4fb9-bdf9-7b537e0bc53a" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">public class DomainProxyService { private readonly Dictionary&lt;Guid, Action&lt;ProxyResponse&gt;&gt; m_dictionaryOfListeners = new Dictionary&lt;Guid, Action&lt;ProxyResponse&gt;&gt;(); private readonly DomainProxy m_domainProxy = new DomainProxy(); public DomainProxyService() { m_domainProxy.ProcessCompleted += DomainProxyProcessCompleted; } private void DomainProxyProcessCompleted(object sender, InvokeEventArgs e) { var proxyResponse = e.ReturnValue as ProxyResponse; if (proxyResponse != null) { //If the dictionary contains listeners for this request if (m_dictionaryOfListeners.ContainsKey(proxyResponse.RequestId)) { m_dictionaryOfListeners[proxyResponse.RequestId].Invoke(proxyResponse); m_dictionaryOfListeners.Remove(proxyResponse.RequestId); } } } public void Process(ProxyRequest proxyRequest, Action&lt;ProxyResponse&gt; callBack) { //Generate a unique id if it doesn't contain an id yet. if (Guid.Empty == proxyRequest.Id) proxyRequest.Id = Guid.NewGuid(); //Add the callback to list of listeners for use on completion. m_dictionaryOfListeners.Add(proxyRequest.Id, callBack); m_domainProxy.Process(proxyRequest); } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p><em> <br />Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-05-16/Silverlight_3_and_RIA_Service_ndash_Cross_Domain_Proxy_Enhanced.aspx Mark Monster http://www.silverlight-help.com/Tips/09-05-16/Silverlight_3_and_RIA_Service_ndash_Cross_Domain_Proxy_Enhanced.aspx e780cd5f-fdc6-4f66-9c1a-28e7772aff75 Sat, 16 May 2009 09:57:06 GMT Silverlight using WCF with Windows Authentication <p>We all know it’s not possible yet to provide credentials when calling WCF Service. I’m telling yet, because <a href="http://mark.mymonster.nl/2009/03/22/silverlight-3-webclient-webrequest-and-wcf-calls-using-credentials/">I saw some signs that we might get support for credentials</a>.</p> <p>But what about now? Yes now, because Silverlight 3 isn’t release to the web yet. </p> <p>Let’s think of all those applications that are running in the Intranet Zone for example. If they are built on the .NET environment, they often make use of Windows Authentication to authenticate the user. And after that make use of the roles assigned to the user to authorize the user. </p> <p>But when we are working in the Silverlight environment we don’t really have the ability to make use of the User that’s already authentication against the Active Directory. But what about the services that Silverlight is using? Well that’s basically what this article is about.</p> <p><strong>Windows Authentication on WCF</strong></p> <p>A few days ago I read an article about <a href="http://www.codeproject.com/KB/WCF/WCFBasicHttpBinding.aspx" target="_blank">Windows Authentication on WCF</a>. This article explains the different steps to get Windows Authentication on WCF very well. But for the sake of this article I will summarize the steps that are required.</p> <ol> <li>Create your WCF Service </li> <li>Ensure authentication mode is Windows by adding &lt;authentication mode=&quot;Windows&quot; /&gt; to the web.config </li> <li>Create the binding in the system.servicemodel element of the web.config just like this. <br /> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:684b1af6-3c41-4d78-ac5b-65e500706631" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">&lt;bindings&gt; &lt;basicHttpBinding&gt; &lt;binding name=&quot;BasicHttpEndpointBinding&quot;&gt; &lt;security mode=&quot;TransportCredentialOnly&quot;&gt; &lt;transport clientCredentialType=&quot;Windows&quot; /&gt; &lt;/security&gt; &lt;/binding&gt; &lt;/basicHttpBinding&gt; &lt;/bindings&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> </li> <li>Make sure the WCF service configuration makes use of the binding created in step 3 by adding the following to the endpoint element for your WCF service. <br /> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:392077cd-3873-407a-8062-1e48cd9ce33b" class="wlWriterEditableSmartContent"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">&lt;endpoint … bindingConfiguration=&quot;BasicHttpEndpointBinding&quot; /&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> </li> <li>The article mentions to disable anonymous access and enable Windows Authentcation. But to make it work on Windows Server 2008 I had to make sure anonymous access was enabled as well.<a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightusingWCFwithWindowsAuthentica_12459-image_2.sflb.ashx"> <br /><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightusingWCFwithWindowsAuthentica_12459-image_thumb.sflb.ashx" width="244" height="113" /></a> </li> <li>If you want authentication to be automated you can do this easily by adding the url of your service to the local intranet zone. </li> <li>Just add a service reference like you would normally do from Silverlight. </li> <li>Create a very simple method to know if it’s working as expected. Something like: <br /> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:7c0458d2-06fc-4c44-9f5c-e28613c2f383" class="wlWriterEditableSmartContent"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4; toolbar: false; ">[OperationContract] public string Hello() { // Add your operation implementation here return string.Format(&quot;Hello, {0} at {1}&quot;, HttpContext.Current.User.Identity.Name, DateTime.Now); }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> </li> </ol> <p>And yes that just works. And this enables more things as well like ask if the user is in a specific role. Basically all the things you’re used to have access to in a Windows Authenticated ASP.NET application are available.</p> <p>I think at least part of the credits for this article should go to Shivprasad koirala who wrote the Code Project article I refer to.</p> <p>Let’s hope the next version of Silverlight enables credentials so we can make use of different authentication scenario’s as well.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-05-12/Silverlight_using_WCF_with_Windows_Authentication.aspx Mark Monster http://www.silverlight-help.com/Tips/09-05-12/Silverlight_using_WCF_with_Windows_Authentication.aspx 9f51220b-9b3b-4b88-a165-84921a9ae3a7 Tue, 12 May 2009 14:00:46 GMT Silverlight on Linux &ndash; Running Moonlight 2.0 Preview 1 <p>Just a few days ago I heard about the <a href="http://go-mono.com/moonlight-preview/" target="_blank">Preview 1 version of Moonlight 2.0</a>. Moonlight is the Open Source version of Silverlight that is able to run on Linux. My first reaction was I want to see this, and as soon as possible. So I downloaded the latest Ubuntu CD’s and started installing it on a Virtual PC. An article meant for installing an older version of <a href="http://arcanecode.com/2008/11/10/installing-ubuntu-810-under-microsoft-virtual-pc-2007/" target="_blank">Ubuntu under Virtual PC</a> helped me.</p> <p>After that it was very easy just go to the <a href="http://go-mono.com/moonlight-preview/" target="_blank">Moonlight 2.0 site</a> and install the Firefox plugin as you would install any other Firefox plugin.</p> <p>First test: Does it run the menu on <a href="http://silverlight.net/" target="_blank">Silverlight.net</a>? Yes it does.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_2.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Silverlight.net&#39;s Silverlight menu is working fine in Moonlight." border="0" alt="Silverlight.net&#39;s Silverlight menu is working fine in Moonlight." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_thumb.sflb.ashx" width="484" height="410" /></a> </p> <p>Second test: Does it run <a href="http://silverlight.net/samples/sl2/toolkitcontrolsamples/run/default.html" target="_blank">the Silverlight Toolkit samples for Silverlight 2</a>? No it doesn’t.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_4.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Silverlight Toolkit for Silverlight 2 crashes Moonlight." border="0" alt="Silverlight Toolkit for Silverlight 2 crashes Moonlight." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_thumb_1.sflb.ashx" width="484" height="410" /></a></p> <p>Third test: Does it run <a href="http://memorabilia.hardrock.com/" target="_blank">the Hard Rock deep-zoom site</a>? Yes it does. </p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_8.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Hard Rock deep-zoom site half loaded in Moonlight." border="0" alt="Hard Rock deep-zoom site half loaded in Moonlight." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_thumb_3.sflb.ashx" width="484" height="410" /></a> </p> <p>Though loading the data is very slow. I’m not sure if that’s because of my network, my vm or Moonlight. After a while this is the new screen.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_10.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Hard Rock deep-zoom site fully loaded in Moonlight." border="0" alt="Hard Rock deep-zoom site fully loaded in Moonlight." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_thumb_4.sflb.ashx" width="484" height="410" /></a> </p> <p>Because the <a href="http://www.mono-project.com/Moonlight/Preview#Release_Notes" target="_blank">release notes</a> mentions that some features that are part of Silverlight 3 are already supported. Fourth test: Does it run <a href="http://silverlight.net/samples/sl3/toolkitcontrolsamples/run/default.html" target="_blank">the Silverlight Toolkit samples for Silverlight 3</a>? No it doesn’t. My whole browser crashed. It was just gone…</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_6.sflb.ashx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Silverlight Toolkit for Silverlight 3 crashes Moonlight and Firefox." border="0" alt="Silverlight Toolkit for Silverlight 3 crashes Moonlight and Firefox." src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-image_thumb_2.sflb.ashx" width="484" height="410" /></a> </p> <p>Alright what did I expect? ?Not much, but it was an interesting test-drive. And for the future I now have a Linux Virtual PC.</p> <p>Let’s hope for more stable Previews of Moonlight.</p> <em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em> http://www.silverlight-help.com/Tips/09-05-06/Silverlight_on_Linux_ndash_Running_Moonlight_2_0_Preview_1.aspx Mark Monster http://www.silverlight-help.com/Tips/09-05-06/Silverlight_on_Linux_ndash_Running_Moonlight_2_0_Preview_1.aspx c39a1606-6120-4dc3-ae56-fd7b68281d1b Wed, 06 May 2009 14:05:40 GMT Silverlight 3 and RIA Service &ndash; Creating a Proxy for Cross Domain HttpRequests <p>One of the first things I thought about after writing my first two articles on RIA Services (<a href="http://mark.mymonster.nl/2009/04/05/silverlight-3-and-ria-services-the-basics/">Basic</a> and <a href="http://mark.mymonster.nl/2009/04/05/silverlight-3-and-ria-services-the-advanced-things/">Advanced</a>) was how I could take advantage of this new technology. </p> <p>The first thing I could thing of was a solution that helps overcoming the Cross Domain Issues when accessing resources on the internet. What about something like a <strong>proxy</strong> service to overcome cross domain issues? Access our known proxy server which will forward the request to the actual resource on the internet.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3andRIAServiceCreatingaProxyf_118CF-image_2.sflb.ashx"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="194" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3andRIAServiceCreatingaProxyf_118CF-image_thumb.sflb.ashx" width="484" border="0" /></a> </p> <p>Let’s first define the interface to communicate through. A very simple ProxyRequest that contains the resource to access on the ‘Any resource’ side, and an Id to make sure we can correctly associate the Request and the Response later on.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:6a92910e-16a2-4fc4-b815-007194dc300b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">namespace MM.Ria.CrossDomainProxy { public class ProxyRequest { [Key] public Guid Id { get; set; } public string Url { get; set; } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>The ProxyResponse is very simple as well. Almost the same as the ProxyRequest a RequestId associated with the Id in the ProxyRequest, the Content and of course something to store any error that occurred.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:fc3071d8-b923-4a03-b395-2de61e4c3ca4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">namespace MM.Ria.CrossDomainProxy { public class ProxyResponse { [Key] public Guid RequestId { get; set; } public string Content { get; set; } public string Error { get; set; } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>And we need an Interface with an Operation, let’s call it process.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:f07405af-9bca-4955-9c4e-e92efb287d1e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">namespace MM.Ria.CrossDomainProxy { public interface IProxy { ProxyResponse Process(ProxyRequest request); } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>We now create the RIA Service implementation, by just delegating everything to a RegularProxy implementation. So this one is simple as well.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:009d84bc-54dd-45dc-8942-dc540bb96986" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">namespace MM.Ria.CrossDomainProxy { [EnableClientAccess] public class DomainProxy : DomainService, IProxy { private readonly RegularProxy m_proxy = new RegularProxy(); [ServiceOperation] public ProxyResponse Process(ProxyRequest request) { return m_proxy.Process(request); } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>And the magic is in the RegularProxy, don’t think we should call it magic though. Just an usage of the WebClient class to download the data from the Url.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:f1bf6c1c-ebea-42db-97d6-8913be394904" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">namespace MM.Ria.CrossDomainProxy { public class RegularProxy : IProxy { public ProxyResponse Process(ProxyRequest request) { var response = new ProxyResponse {RequestId = request.Id}; try { using (var client = new WebClient()) { string data = client.DownloadString(request.Url); response.Content = data; } } catch (Exception exception) { response.Error = exception.Message; } return response; } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Don’t forget this is a very basic Proxy implementation and doesn’t implement all the features we can think of. But this first basic set up can easily be enhanced with for example Credentials support, Caching and other things as well.</p> <p>But how can we use it in our Silverlight application? Simple as well.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:c00d7088-e544-4e50-bbce-1f6e0e3cae67" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: false; ">var domainProxy = new DomainProxy(); domainProxy.ProcessCompleted += (sender, e) =&gt; Debug.WriteLine((e.ReturnValue as ProxyResponse).Content); domainProxy.Process(new ProxyRequest { Id = Guid.NewGuid(), Url = &quot;http://www.silverlight.net/&quot; });</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Looks like the keyword is <strong>simple</strong> when we’re creating RIA Services. I really like it.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-04-09/Silverlight_3_and_RIA_Service_ndash_Creating_a_Proxy_for_Cross_Domain_HttpRequests.aspx Mark Monster http://www.silverlight-help.com/Tips/09-04-09/Silverlight_3_and_RIA_Service_ndash_Creating_a_Proxy_for_Cross_Domain_HttpRequests.aspx 72c34a82-c2b8-486e-b875-353e176bc0a6 Thu, 09 Apr 2009 13:55:32 GMT Silverlight 3 and RIA Services &ndash; The advanced things <p>My last article was about <a href="http://mark.mymonster.nl/2009/04/05/silverlight-3-and-ria-services-the-basics/">the basics of RIA Services</a>. This article goes about the more advanced things in RIA Services. This article contains a few things that make the usage of RIA Services in more advanced scenario’s possible.</p> <ul> <li>Complex Types in RIA Services </li> <li>RIA Services in a separate class library </li> <li>RIA Services and Out of browser mode </li> <li>RIA Services on a different host </li> </ul> <p><strong>Using Complex Types in RIA Services</strong></p> <p>In my other article I just made use just a string as input parameter and a string as output parameter. It’s however very well possible to use custom types instead. There’s hower one prerequisite for those custom types.</p> <ul> <li>Each Custom Type needs to have one property decorated with a <strong>KeyAttribute</strong>. This is required for input and output types. </li> </ul> <p>I created a WorldRequest and a WorldResponse which fits nicely in the example for HelloWorld.</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:89a81f83-8033-44a9-800d-b8e5106ae08f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">public class WorldRequest { [Key] public string Name { get; set; } } public class WorldResponse { [Key] public string Greeting { get; set; } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>This can be used in the HelloWorldDomainService just like you would do in a normal class.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:6e8ab9a6-9126-48ec-a093-a7ca683d842f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">[EnableClientAccess] public class HelloWorldDomainService : DomainService { [ServiceOperation] public WorldResponse HelloWorld(WorldRequest worldRequest) { return new WorldResponse { Greeting = string.Format(&quot;Hello {0}.&quot;, worldRequest.Name) }; } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>After compilation those custom types get generated in the Silverlight project as well as we saw in my previous article. The Custom Type is now overloaded from <strong>Entity</strong>. And has a specific method called <strong>GetIdentity</strong>. This has something to do with the KeyAttribute that’s required to add to one property inside a custom types. Although this is probably necessary for integration with the Entity Framework it doesn’t make sense in my example.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:6a07d405-9763-42f3-8668-fd67c79c252f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">[DataContract(Namespace=&quot;http://schemas.datacontract.org/2004/07/MM.Ria&quot;)] public sealed partial class WorldRequest : Entity { private string _name; [DataMember()] [Key()] public string Name { get { return this._name; } set { if ((this._name != value)) { this.ValidateProperty(&quot;Name&quot;, value); this.RaiseDataMemberChanging(&quot;Name&quot;); this._name = value; this.RaiseDataMemberChanged(&quot;Name&quot;); } } } public override object GetIdentity() { return this._name; } } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>We can now easily use this generated class as we would have done in different scenario’s.</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:24c6f3d8-c73f-44a4-b707-1b4cdeda6469" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">var helloWorld = new HelloWorldDomainContext(); helloWorld.HelloWorldCompleted += HelloWorldHelloWorldCompleted; helloWorld.HelloWorld(new WorldRequest{Name = &quot;Mark Monster&quot;});</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>And in the EventHandler we have to cast the ReturnValue property to the <strong>WorldResponse</strong> type. Again I hope they make InvokeEventArgs a generic type so that we don’t have to cast this ReturnValue and have it return the correct type.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:0f8d2aef-7e47-47c5-829e-431bea09e8e4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">private void HelloWorldHelloWorldCompleted(object sender, InvokeEventArgs e) { Debug.WriteLine((e.ReturnValue as WorldResponse).Greeting); }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p><strong>Move code for the RIA Service to a class library</strong></p> <p>Next thing that came in my mind was the fact what if I want to share my RIA Services with other people? Do they need to have the source or is a different approach possible?</p> <p>Luckily it’s possible to create class library (standard .NET) add references to a few dlls.</p> <p><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="148" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3andRIAServicesTheadvancedthi_DCCB-image_3.sflb.ashx" width="305" border="0" /> </p> <p>After that just move your RIA Service code in there. This library can now be used in any Web project that’s linked to a Silverlight application. Just add a reference to the new library containing your RIA Service and while building code will get generated in your Silverlight application.</p> <p><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="182" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-Silverlight3andRIAServicesTheadvancedthi_DCCB-image_6.sflb.ashx" width="235" border="0" /> </p> <p><strong>What about using RIA Services in the Out of browser mode?</strong></p> <p>It just works. I didn’t have to do anything to make the Out of browser version communicate with the RIA Services. </p> <p><strong>When the host running the RIA Services is different from the url hosting the Silverlight application?</strong></p> <p>Of course in some scenario’s the RIA Services are hosted on a different location than the Silverlight application itself. Of course you have to remind yourself about cross domain issues, so make sure the host has a <strong>clientaccesspolicy.xml</strong> or <strong>crossdomain.xml</strong> file in place.</p> <p>When we take a closer look into the generated code we’ll find a default constructor and a constructor where you can specify the service URI.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:eb3567b8-2951-417d-bba2-723283c5ad35" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">/// &lt;summary&gt; /// Default constructor. /// &lt;/summary&gt; public HelloWorldDomainContext() : base(new HttpDomainClient(new Uri(&quot;DataService.axd/MM-Ria-HelloWorldDomainService/&quot;, System.UriKind.Relative))) { } /// &lt;summary&gt; /// Constructor used to specify a data service URI. /// &lt;/summary&gt; /// &lt;param name=&quot;serviceUri&quot;&gt; /// The HelloWorldDomainService data service URI. /// &lt;/param&gt; public HelloWorldDomainContext(Uri serviceUri) : base(new HttpDomainClient(serviceUri)) { }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>We can now make use of the constructor which accepts a serviceUri to connect to the RIA Service that’s running at a different location. The tricky part however is the <strong>DataService.axd/MM-Ria-HelloWorldDomainService/</strong> part. Besides DataService.axd it contains also the namespace and type name for the RIA Service, but instead of using dots to separate the namespace parts and the type name dashes are used. But for the easy parts, just copy it from the generated code I would say.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:ae241e61-61a5-4ea9-ac74-3a3bf4297121" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">var helloWorld = new HelloWorldDomainContext(new Uri(&quot;http://myhostruningsomewhere.com/DataService.axd/MM-Ria-HelloWorldDomainService/&quot;, UriKind.Absolute)); helloWorld.HelloWorldCompleted += HelloWorldHelloWorldCompleted; helloWorld.HelloWorld(new WorldRequest {Name = &quot;Mark Monster&quot;}); </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-04-05/Silverlight_3_and_RIA_Services_ndash_The_advanced_things.aspx Mark Monster http://www.silverlight-help.com/Tips/09-04-05/Silverlight_3_and_RIA_Services_ndash_The_advanced_things.aspx 595db7df-b669-4d15-a103-ace22b2f1771 Sun, 05 Apr 2009 09:38:35 GMT Silverlight 3 and RIA Services &ndash; The basics <p>At the Mix 09 conference Microsoft announced a new technology called RIA Services. This new technology simplifies the communication between the RIA Client Technologies like Ajax and Silverlight and the Server technology ASP.NET. </p> <p>Everybody who has been using Silverlight 2 knows about the lack of support for specific features that we’re used to make use of in for example ASP.NET. And yes, we need to remember that Silverlight is a technology that runs inside the browser (<a href="http://mark.mymonster.nl/2009/03/22/silverlight-3-out-of-browser-support/">or outside the browser when activated the specific Silverlight 3 Beta feature</a>).</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightandRIAServices_E786-image_2.sflb.ashx"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="260" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightandRIAServices_E786-image_thumb.sflb.ashx" width="480" border="0" /></a></p> <p>Let’s start with a very simple RIA Service and let’s call it HelloWorldDomainService. I’ve seen other articles about RIA Services but they most of the time dive deep by combining the Entity Framework right away.</p> <p><strong>First thing: what special things does a RIA Service need?</strong></p> <ul> <li>The RIA Service needs to be derived from <strong>DomainService</strong>, or from a different class that’s derived from <strong>DomainService</strong>. </li> <li>The RIA Service needs to be decorated with an attribute called <strong>EnableClientAccessAttribute</strong>. </li> <li>The operations need to be decorated with an attribute called <strong>ServiceOperationAttribute</strong>. </li> </ul> <p>A very simple <strong>HelloWorldDomainService</strong> now looks like this (this class needs to be in the ASP.NET Project, not the Silverlight project).</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:fb9a8a59-3f86-44c3-8a99-b98ad06ded80" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">[EnableClientAccess] public class HelloWorldDomainService : DomainService { [ServiceOperation] public string HelloWorld(string name) { return string.Format(&quot;Hello {0}.&quot;, name); } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p><strong>Second thing that’s important is the configuration is correct. </strong></p> <p>So what’s required? A configuration for a new HttpHandler specially for RIA Services in general. Just add this piece in the HttpHandlers part of the Web.config.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:459d5b54-ede3-4bbd-9dba-23f092242212" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: xml; gutter: false; first-line: 1; tab-size: 2; toolbar: true; ">&lt;add path=&quot;DataService.axd&quot; verb=&quot;GET,POST&quot; type=&quot;System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot; validate=&quot;false&quot;/&gt;</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p><strong>Next thing is getting the Silverlight project bound to the ASP.NET project.</strong></p> <p>When you right click on the Silverlight project and choose properties you’ll get something similar to this.</p> <p><a href="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightandRIAServices_E786-image_4.sflb.ashx"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="306" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightandRIAServices_E786-image_thumb_1.sflb.ashx" width="484" border="0" /></a> </p> <p>Select the ASP.NET server project link to the ASP.NET server project that contains the RIA Services. In this example the ASP.NET server project is called <strong>MM.Sl3Experiments.Web</strong>.</p> <p><strong>Let’s build the whole solution…</strong></p> <p>… what happens? Let’s have a look at all files (also hidden files) in the Silverlight project by hitting the <strong>show all files</strong> button in the solution explorer. And you will suddenly see a folder called <strong>Generated_Code</strong> containing a file alike to <strong>&lt;WebProjectName&gt;.g.cs</strong>.</p> <p><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="211" alt="image" src="http://www.silverlight-help.com/Libraries/MetaBlogLib/WindowsLiveWriter-SilverlightandRIAServices_E786-image_7.sflb.ashx" width="273" border="0" /> </p> <p>So there’s a lot of code generation behind the scenes? Yes it is. And that’s why I recommend people to write kind of a Service Agent so you’re not actually calling the generated code directly. But that’s something for a different post, or something you can figure out yourself. We’re now talking about RIA Services specifically.</p> <p><strong>But what gets generated?</strong></p> <p>For the sake of this article I removed a lot of code from this generated class, things that are just there but have no real purpose in this example. What we have left is this:</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:df26e6cc-1546-469f-a57b-cd071af03b29" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">public sealed partial class HelloWorldDomainContext : DomainContext { public HelloWorldDomainContext() : base(new HttpDomainClient(new Uri(&quot;DataService.axd/MM-Sl3Experiments-Web-HelloWorldDomainService/&quot;, System.UriKind.Relative))) { } public event System.EventHandler&lt;InvokeEventArgs&gt; HelloWorldCompleted; public void HelloWorld(string name) { Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;(); parameters.Add(&quot;name&quot;, name); base.InvokeServiceOperation(&quot;HelloWorld&quot;, typeof(string), parameters, this.OnHelloWorldCompleted, null); } private void OnHelloWorldCompleted(InvokeEventArgs args) { if ((HelloWorldCompleted != null)) { this.HelloWorldCompleted(this, args); } } } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>What we have in the generated code are the following things:</p> <ol> <li>A constructor to create a HelloWorldDomainContext. </li> <li>A method that’s called <strong>HelloWorld</strong> with typed arguments. </li> <li>An event that get’s called upon completion of the HelloWorld execution. </li> </ol> <p>So we can easily write this code inside our Silverlight application to call the HelloWorldDomainService that’s really running on the ASP.NET Server side.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:56f81d15-3199-4dc2-b7b3-e51397b8537e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">var helloWorld = new HelloWorldDomainContext(); helloWorld.HelloWorldCompleted += new EventHandler&lt;InvokeEventArgs&gt;(HelloWorldHelloWorldCompleted); helloWorld.HelloWorld(&quot;Mark Monster&quot;);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Just very simple, create a new object, attach to the Completed event and call the method.</p> <p>The method being called upon completion only prints the return value to the Debug window.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:29fa3076-bda4-400f-b8e3-b56753ce44bc" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">private void HelloWorldHelloWorldCompleted(object sender, InvokeEventArgs e) { Debug.WriteLine(e.ReturnValue as String); } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p><strong>Places for improvement for RIA Services…</strong></p> <p>One thing that can be made better is the fact that InvokeEventArgs doesn’t have typed property ReturnValue. It’s of type object, and you still need to cast it to the right type. A recommendation for the team behind RIA services would be to make InvokeEventArgs generic (InvokeEventArgs&lt;T&gt;) to make something like this possible:</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:76b76f17-6e5b-4197-8c5c-a334a30971b1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">/// &lt;summary&gt; /// The generated class /// &lt;/summary&gt; public sealed partial class HelloWorldDomainContext : DomainContext { public HelloWorldDomainContext() : base(new HttpDomainClient(new Uri(&quot;DataService.axd/MM-Sl3Experiments-Web-HelloWorldDomainService/&quot;, System.UriKind.Relative))) { } public event System.EventHandler&lt;InvokeEventArgs&lt;string&gt;&gt; HelloWorldCompleted; public void HelloWorld(string name) { Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;(); parameters.Add(&quot;name&quot;, name); base.InvokeServiceOperation(&quot;HelloWorld&quot;, typeof(string), parameters, this.OnHelloWorldCompleted, null); } private void OnHelloWorldCompleted(InvokeEventArgs&lt;string&gt; args) { if ((HelloWorldCompleted != null)) { this.HelloWorldCompleted(this, args); } } }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>And an improved way of using. The <strong>ReturnValue</strong> is now typed.</p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:76ed1482-180a-4a7a-a2b9-086f12770269" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 2; toolbar: true; ">var helloWorld = new HelloWorldDomainContext(); helloWorld.HelloWorldCompleted += new EventHandler&lt;InvokeEventArgs&lt;string&gt;&gt;(HelloWorldHelloWorldCompleted); helloWorld.HelloWorld(&quot;Mark Monster&quot;); private void HelloWorldHelloWorldCompleted(object sender, InvokeEventArgs&lt;string&gt; e) { Debug.WriteLine(e.ReturnValue); }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Another improvement would be to include the generated files in the project. This is because of two reasons. The first and most important reason would be Source Control. I think we want to have those generated files under Source Control as well. We now would have to add those files manually to source control, or right click on those generated items to include them in the project, so the Source Control Systems will pick them up automatically.</p> <p>The second reason I want those files to be included is: ReSharper, although I know it’s not a product by Microsoft. Because the generated files are not part of the project,&#160; I won’t be able to make use of ReSharper’s intellisense and what about the ReSharper Code Analysis?</p> <p>In the end I really like this ability to run code on the server side this easily. I know RIA Services is still in CTP, let’s hope for a few improvements. It’s already a good product, but it could be even better.</p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-04-05/Silverlight_3_and_RIA_Services_ndash_The_basics.aspx Mark Monster http://www.silverlight-help.com/Tips/09-04-05/Silverlight_3_and_RIA_Services_ndash_The_basics.aspx 44b856dc-e24c-4825-9fd8-1fe9cc9a4ff5 Sun, 05 Apr 2009 07:00:59 GMT In memory cache for Silverlight 2 and 3 <p>I’ve seen some people talking about Silverlight Caching on the <a href="http://silverlight.net/forums/" target="_blank">Silverlight forum</a>. And because there’s no solution that can be compared to for example the ASP.NET solution for Caching. Of course it’s not that difficult to keep some data in a simple reference, just a variable, maybe on global maybe on class level. But yes, if you want a little bit more advanced Cache which supports the expiring of data you’ll need something different.</p> <p>For the general purpose of caching data which can expire after a certain timespan I wrote this solution that can be used in Silverlight 2 and 3. You can view the whole code at the end of this article.</p> <p><strong>Adding and getting data from Cache</strong></p> <p>I wanted a solution that could work with general objects the way I work in this example.</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:e62ece65-45a9-470e-b6e8-5e6187fca2c7" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: true; ">Cache.Current.Add(&quot;Testkey&quot;, 10, TimeSpan.FromMinutes(2)); object cacheData = Cache.Current.Get(&quot;Testkey&quot;); if(cacheData!=null) { int cacheDataTyped = (int) cacheData; }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>In those situations you will have to cast the data to the required Type or Structure. This works fine, we’ve done this before while accessing the ASP.NET Cache. But sometimes you’ll want to have it typed immediately. So I want to be able to use this as well.</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:2ab3e4ba-cc41-4782-aa02-7beb8fcaa4ff" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: true; ">User user = GetUser(); Cache.Current.Add(&quot;Testkeytyped&quot;, user, TimeSpan.FromMinutes(4)); User userFromCache = Cache.Current.Get&lt;User&gt;(&quot;Testkeytyped&quot;);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>So I had to add a Generic function Get and a none Generic function Get. I did this, and the code above works fine indeed.</p> <p><strong>But what about expiring data?</strong></p> <p>To expire data I wanted to provide a TimeSpan while adding the item to the cache. The first solution I thought of was to remove items upon get if it’s no longer valid. But in the end I thought what if the amount of data is large, in those cases you want it removed as soon as it is expired. So I found a different solution. By making use of the <a href="http://msdn.microsoft.com/en-us/library/system.threading.timer(VS.95).aspx" target="_blank">Timer class</a> in Silverlight. I want the timer to tick every minute, and on tick I want it to clean the cache. So the current solutions cleans up items in the cache every minute. And upon getting of items it will check if the item is still valid or not.</p> <p>Please feel free to use this is solution. It’s not thread-safe, but you can add thread-safe support yourself if you want to.</p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:e4173ec9-35ca-4ca8-961e-2e2f6b18ad56" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: true; ">/// &lt;summary&gt; /// Class supports in memory cache for Silverlight applications. Silverlight 2 and 3 are supported. /// Each minute the cache items are iterated for validility, invalid cache items are removed. /// &lt;/summary&gt; public class Cache : IDisposable { public static Cache Current = new Cache(); private readonly IDictionary&lt;string, CacheItem&gt; _cacheItems = new Dictionary&lt;string, CacheItem&gt;(); private readonly TimeSpan _period = TimeSpan.FromMinutes(1); private readonly TimeSpan _startTimeSpan = TimeSpan.Zero; private readonly TimeSpan _stopTimeSpan = TimeSpan.FromMilliseconds(-1); private readonly Timer _timer; private TimerState _state = TimerState.Stopped; private Cache() { _timer = new Timer(CleanUpItems, this, _stopTimeSpan, _period); } /// &lt;summary&gt; /// All the CacheItems are in a Dictionary /// &lt;/summary&gt; public IDictionary&lt;string, CacheItem&gt; CacheItems { get { return _cacheItems; } } /// &lt;summary&gt; /// Get full CacheItem based on key. /// &lt;/summary&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;returns&gt;The CacheItem stored for the given key, if it is still valid. Otherwise null.&lt;/returns&gt; public CacheItem this[string key] { get { if (CacheItems.ContainsKey(key)) { CacheItem ci = CacheItems[key]; if (ci.IsValid()) return CacheItems[key]; } return null; } set { CacheItems[key] = value; } } #region IDisposable Members public void Dispose() { _timer.Dispose(); } #endregion /// &lt;summary&gt; /// Get data typed directly for given key. /// &lt;/summary&gt; /// &lt;typeparam name=&quot;T&quot;&gt;The Type for which the data is set. If the type is wrong null will be returned.&lt;/typeparam&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;returns&gt;The data typed for the given key, if it is still valid. Otherwise null.&lt;/returns&gt; public T Get&lt;T&gt;(string key) where T : class { CacheItem item = this[key]; if (item != null) return item.GetData&lt;T&gt;(); return null; } /// &lt;summary&gt; /// Get data untyped directly for given key. /// &lt;/summary&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;returns&gt;The data untyped for the given key, if it is still valid. Otherwise null.&lt;/returns&gt; public object Get(string key) { CacheItem item = this[key]; if (item != null) return item.GetData(); return null; } private void StartTimer() { if (_state == TimerState.Stopped) { _timer.Change(_startTimeSpan, _period); _state = TimerState.Started; } } private void StopTimer() { if (_state == TimerState.Started) { _timer.Change(_stopTimeSpan, _period); _state = TimerState.Stopped; } } /// &lt;summary&gt; /// Clean up items that are not longer valid. /// &lt;/summary&gt; /// &lt;param name=&quot;state&quot;&gt;Expect state to be the cache object.&lt;/param&gt; private static void CleanUpItems(object state) { var cache = state as Cache; if (cache != null) { List&lt;KeyValuePair&lt;string, CacheItem&gt;&gt; itemsToRemove = cache.CacheItems.Where(i =&gt; !i.Value.IsValid()).ToList(); foreach (var item in itemsToRemove) { cache.CacheItems.Remove(item.Key); } if (cache.CacheItems.Count == 0) cache.StopTimer(); } } /// &lt;summary&gt; /// Add a new item to the cache. If the key is already used it will be overwritten. /// &lt;/summary&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt; public void Add(string key, CacheItem value) { if (_cacheItems.ContainsKey(key)) _cacheItems.Remove(key); _cacheItems.Add(key, value); StartTimer(); } /// &lt;summary&gt; /// Add a new item to the cache. If the key is already used it will be overwritten. /// &lt;/summary&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;param name=&quot;data&quot;&gt;The data to cache.&lt;/param&gt; /// &lt;param name=&quot;validDuration&quot;&gt;The duration of the caching of the data.&lt;/param&gt; public void Add(string key, object data, TimeSpan validDuration) { Add(key, new CacheItem(data, validDuration)); } /// &lt;summary&gt; /// Removes the item for the given key from the cache. /// &lt;/summary&gt; /// &lt;param name=&quot;key&quot;&gt;The key for which a CacheItem is stored.&lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; public bool Remove(string key) { bool remove = _cacheItems.Remove(key); if (_cacheItems.Count == 0) StopTimer(); return remove; } #region Nested type: TimerState /// &lt;summary&gt; /// Used for determing TimerState /// &lt;/summary&gt; private enum TimerState { Stopped, Started } #endregion }</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:7ae3f27a-86f7-409c-8ac5-9ff83061e598" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 2; toolbar: true; ">/// &lt;summary&gt; /// Defines an item that's stored in the Cache. /// &lt;/summary&gt; public class CacheItem { private readonly DateTime _creationDate = DateTime.Now; private readonly TimeSpan _validDuration; /// &lt;summary&gt; /// Constructs a cache item with for the data with a validity of validDuration. /// &lt;/summary&gt; /// &lt;param name=&quot;data&quot;&gt;The data for the cache.&lt;/param&gt; /// &lt;param name=&quot;validDuration&quot;&gt;The duration for the data being valid in the cache.&lt;/param&gt; public CacheItem(object data, TimeSpan validDuration) { _validDuration = validDuration; Data = data; } /// &lt;summary&gt; /// The data in the Cache. /// &lt;/summary&gt; public object Data { set; private get; } /// &lt;summary&gt; /// Gets the Data typed. /// &lt;/summary&gt; /// &lt;typeparam name=&quot;T&quot;&gt;The Type for which the data is set. If the type is wrong null will be returned.&lt;/typeparam&gt; /// &lt;returns&gt;The data typed.&lt;/returns&gt; public T GetData&lt;T&gt;() where T : class { return Data as T; } /// &lt;summary&gt; /// Gets the Data untyped. /// &lt;/summary&gt; /// &lt;returns&gt;The data untyped.&lt;/returns&gt; public object GetData() { return Data; } /// &lt;summary&gt; /// Check if the Data is still valid. /// &lt;/summary&gt; /// &lt;returns&gt;Valid if the validDuration hasn't passed.&lt;/returns&gt; public bool IsValid() { return _creationDate.Add(_validDuration) &gt; DateTime.Now; } } </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p><em>Ps. This article is cross posted on: </em><a href="http://mark.mymonster.nl"><em>Mark Monster’s blog</em></a><em> and </em><a href="http://www.silverlight-help.com/Home.aspx"><em>Silverlight Help</em></a><em>.</em></p> http://www.silverlight-help.com/Tips/09-03-29/In_memory_cache_for_Silverlight_2_and_3.aspx Mark Monster http://www.silverlight-help.com/Tips/09-03-29/In_memory_cache_for_Silverlight_2_and_3.aspx 884f9289-ab64-4cac-ad3d-b9144f36bcc5 Sun, 29 Mar 2009 08:30:00 GMT