<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>tsJensen.com - Azure</title>
    <link>http://www.tsjensen.com/blog/</link>
    <description />
    <language>en-us</language>
    <copyright>Tyler Jensen</copyright>
    <lastBuildDate>Mon, 30 Nov 2009 02:13:26 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8139.823</generator>
    <managingEditor>tyler@tsjensen.com</managingEditor>
    <webMaster>tyler@tsjensen.com</webMaster>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=1bc5872b-9601-428f-ad70-f90999085525</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1bc5872b-9601-428f-ad70-f90999085525</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It turns out that using table storage in Windows Azure 1.0 is quite easily done with
a minimal amount of configuration. In the new Azure cloud service Visual Studio project
template, configuration is significantly simpler than what I ended up with in a previous
blog post where I was able to get the new WCF RIA Services working with the new Windows
Azure 1.0 November 2009 release and the AspProvider code from the updated demo. 
</p>
        <p>
And while the project runs as expected on my own machine, I can’t seem to get it to
run in the cloud for some reason. I have not solved that problem. Since I can’t seem
to get much of a real reason for the failure via the Azure control panel, I’ve decided
to start at the beginning, taking each step to the cloud rather than building entirely
on the local simulation environment before taking it to the cloud for test.
</p>
        <p>
I started with a clean solution. No changes except to the web role’s Default.aspx
page with some static text. Publish to the cloud and twenty to thirty minutes later
(too long in my opinion) the page will come up, deployment is complete and the equivalent
of a “hello world” app is running in the Azure cloud.
</p>
        <p>
The next step I want to experiment with is the simplest use possible of Azure table
storage. In the previous project, there was a lot of configuration. In this new project,
there was very little. I wondered how much of the configuration from the previous
project, largely an import from the updated AspProviders demo project, was a partially
unnecessary legacy of CTP bits. It turns out, nearly all of it.
</p>
        <p>
Here’s the only configuration you need for accessing Azure storage:
</p>
        <pre class="brush: xml;" name="code">&lt;?xml version="1.0"?&gt;
&lt;ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"&gt;
  &lt;Role name="MyFiles"&gt;
    &lt;Instances count="1" /&gt;
    &lt;ConfigurationSettings&gt;
      &lt;!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      &lt;Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&gt;
      &lt;Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&gt;
      --&gt;

      &lt;!-- local settings --&gt;
      &lt;Setting name="DataConnectionString" value="UseDevelopmentStorage=true" /&gt;
      &lt;Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" /&gt;
    &lt;/ConfigurationSettings&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;</pre>
        <p>
The thumbnails sample does provide one important piece of code that does not come
with the standard Visual Studio template. It goes in the WebRole.cs file and makes
the use of the CloudStorageAccount class’s static FromConfigurationSetting method
which returns the needed CloudStorageAccount instance. To use that method, the SetConfigurationSettingPublisher
method must have already been called. Hence this code placed in the WebRole class
like this: 
</p>
        <pre class="brush: c-sharp;" name="code">public class WebRole : RoleEntryPoint
{
  public override bool OnStart()
  {
    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    #region Setup CloudStorageAccount Configuration Setting Publisher

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =&gt;
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =&gt;
      {
        if (arg.Changes.OfType&lt;RoleEnvironmentConfigurationSettingChange&gt;()
           .Any((change) =&gt; (change.ConfigurationSettingName == configName)))
        {
          // The corresponding configuration setting has changed, propagate the value
          if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
          {
            // In this case, the change to the storage account credentials in the
            // service configuration is significant enough that the role needs to be
            // recycled in order to use the latest settings. (for example, the 
            // endpoint has changed)
            RoleEnvironment.RequestRecycle();
          }
        }
      };
    });
    #endregion

    return base.OnStart();
  }

  private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
  {
    // If a configuration setting is changing
    if (e.Changes.Any(change =&gt; change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}</pre>
        <p>
Once you have the set the configuration setting publisher, you can use the FromConfigurationSetting
method in the creation of your CloudTableClient and then check for the existence of
a table, creating it if it does not already exist in your repository code. Here’s
a minimal example that I used and published successfully to my Azure account.
</p>
        <pre class="brush: c-sharp;" name="code">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.Data.Services.Client;

namespace MyDemo
{
  public class AdventureRow : TableServiceEntity
  {
    public string IpAddress { get; set; }
    public DateTime When { get; set; }
  }

  public class AdventureRepository
  {
    private const string _tableName = "Adventures";
    private CloudStorageAccount _account;
    private CloudTableClient _client;

    public AdventureRepository()
    {
      _account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
      _client = new CloudTableClient(_account.TableEndpoint.ToString(), _account.Credentials);
      _client.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
      _client.CreateTableIfNotExist(_tableName);
    }

    public AdventureRow InsertAdventure(AdventureRow row)
    {
      row.PartitionKey = "AdventurePartitionKey";
      row.RowKey = Guid.NewGuid().ToString();
      var svc = _client.GetDataServiceContext();
      svc.AddObject(_tableName, row);
      svc.SaveChanges();
      return row;
    }

    public List&lt;AdventureRow&gt; GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery&lt;AdventureRow&gt; queryService = svc.CreateQuery&lt;AdventureRow&gt;(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable&lt;AdventureRow&gt; rows = query.Execute();
      List&lt;AdventureRow&gt; list = new List&lt;AdventureRow&gt;(rows);
      return list;
    }
  }
}</pre>
        <p>
Just as the StorageClient has moved from “sample” to first class library in the Azure
SDK, I suspect that the AspProviders sample may already be on that same path to glory.
In it’s current form, it represents something new and something old, the old having
not been entirely cleaned up, lacking the elegance it deserves and will likely get
either by Microsoft or some other enterprising Azure dev team.
</p>
        <p>
As for me, I will continue trying to learn, one step at a time, why the Adventure
code I blogged about previously will run locally but not on the cloud as expected.
Who knows, it could be as simple as a single configuration gotcha, but figuring it
out one step at a time will be a great learning opportunity and as I get the time,
I’ll share what I learn here.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1bc5872b-9601-428f-ad70-f90999085525" />
      </body>
      <title>Windows Azure 1.0 CloudTableClient Minimal Configuration</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/11/30/Windows+Azure+10+CloudTableClient+Minimal+Configuration.aspx</link>
      <pubDate>Mon, 30 Nov 2009 02:13:26 GMT</pubDate>
      <description>&lt;p&gt;
It turns out that using table storage in Windows Azure 1.0 is quite easily done with
a minimal amount of configuration. In the new Azure cloud service Visual Studio project
template, configuration is significantly simpler than what I ended up with in a previous
blog post where I was able to get the new WCF RIA Services working with the new Windows
Azure 1.0 November 2009 release and the AspProvider code from the updated demo. 
&lt;/p&gt;
&lt;p&gt;
And while the project runs as expected on my own machine, I can’t seem to get it to
run in the cloud for some reason. I have not solved that problem. Since I can’t seem
to get much of a real reason for the failure via the Azure control panel, I’ve decided
to start at the beginning, taking each step to the cloud rather than building entirely
on the local simulation environment before taking it to the cloud for test.
&lt;/p&gt;
&lt;p&gt;
I started with a clean solution. No changes except to the web role’s Default.aspx
page with some static text. Publish to the cloud and twenty to thirty minutes later
(too long in my opinion) the page will come up, deployment is complete and the equivalent
of a “hello world” app is running in the Azure cloud.
&lt;/p&gt;
&lt;p&gt;
The next step I want to experiment with is the simplest use possible of Azure table
storage. In the previous project, there was a lot of configuration. In this new project,
there was very little. I wondered how much of the configuration from the previous
project, largely an import from the updated AspProviders demo project, was a partially
unnecessary legacy of CTP bits. It turns out, nearly all of it.
&lt;/p&gt;
&lt;p&gt;
Here’s the only configuration you need for accessing Azure storage:
&lt;/p&gt;
&lt;pre class="brush: xml;" name="code"&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"&amp;gt;
  &amp;lt;Role name="MyFiles"&amp;gt;
    &amp;lt;Instances count="1" /&amp;gt;
    &amp;lt;ConfigurationSettings&amp;gt;
      &amp;lt;!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      &amp;lt;Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&amp;gt;
      &amp;lt;Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&amp;gt;
      --&amp;gt;

      &amp;lt;!-- local settings --&amp;gt;
      &amp;lt;Setting name="DataConnectionString" value="UseDevelopmentStorage=true" /&amp;gt;
      &amp;lt;Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" /&amp;gt;
    &amp;lt;/ConfigurationSettings&amp;gt;
  &amp;lt;/Role&amp;gt;
&amp;lt;/ServiceConfiguration&amp;gt;&lt;/pre&gt;
&lt;p&gt;
The thumbnails sample does provide one important piece of code that does not come
with the standard Visual Studio template. It goes in the WebRole.cs file and makes
the use of the CloudStorageAccount class’s static FromConfigurationSetting method
which returns the needed CloudStorageAccount instance. To use that method, the SetConfigurationSettingPublisher
method must have already been called. Hence this code placed in the WebRole class
like this: 
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;public class WebRole : RoleEntryPoint
{
  public override bool OnStart()
  {
    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    #region Setup CloudStorageAccount Configuration Setting Publisher

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =&amp;gt;
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =&amp;gt;
      {
        if (arg.Changes.OfType&amp;lt;RoleEnvironmentConfigurationSettingChange&amp;gt;()
           .Any((change) =&amp;gt; (change.ConfigurationSettingName == configName)))
        {
          // The corresponding configuration setting has changed, propagate the value
          if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
          {
            // In this case, the change to the storage account credentials in the
            // service configuration is significant enough that the role needs to be
            // recycled in order to use the latest settings. (for example, the 
            // endpoint has changed)
            RoleEnvironment.RequestRecycle();
          }
        }
      };
    });
    #endregion

    return base.OnStart();
  }

  private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
  {
    // If a configuration setting is changing
    if (e.Changes.Any(change =&amp;gt; change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
Once you have the set the configuration setting publisher, you can use the FromConfigurationSetting
method in the creation of your CloudTableClient and then check for the existence of
a table, creating it if it does not already exist in your repository code. Here’s
a minimal example that I used and published successfully to my Azure account.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.Data.Services.Client;

namespace MyDemo
{
  public class AdventureRow : TableServiceEntity
  {
    public string IpAddress { get; set; }
    public DateTime When { get; set; }
  }

  public class AdventureRepository
  {
    private const string _tableName = "Adventures";
    private CloudStorageAccount _account;
    private CloudTableClient _client;

    public AdventureRepository()
    {
      _account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
      _client = new CloudTableClient(_account.TableEndpoint.ToString(), _account.Credentials);
      _client.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
      _client.CreateTableIfNotExist(_tableName);
    }

    public AdventureRow InsertAdventure(AdventureRow row)
    {
      row.PartitionKey = "AdventurePartitionKey";
      row.RowKey = Guid.NewGuid().ToString();
      var svc = _client.GetDataServiceContext();
      svc.AddObject(_tableName, row);
      svc.SaveChanges();
      return row;
    }

    public List&amp;lt;AdventureRow&amp;gt; GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery&amp;lt;AdventureRow&amp;gt; queryService = svc.CreateQuery&amp;lt;AdventureRow&amp;gt;(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable&amp;lt;AdventureRow&amp;gt; rows = query.Execute();
      List&amp;lt;AdventureRow&amp;gt; list = new List&amp;lt;AdventureRow&amp;gt;(rows);
      return list;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
Just as the StorageClient has moved from “sample” to first class library in the Azure
SDK, I suspect that the AspProviders sample may already be on that same path to glory.
In it’s current form, it represents something new and something old, the old having
not been entirely cleaned up, lacking the elegance it deserves and will likely get
either by Microsoft or some other enterprising Azure dev team.
&lt;/p&gt;
&lt;p&gt;
As for me, I will continue trying to learn, one step at a time, why the Adventure
code I blogged about previously will run locally but not on the cloud as expected.
Who knows, it could be as simple as a single configuration gotcha, but figuring it
out one step at a time will be a great learning opportunity and as I get the time,
I’ll share what I learn here.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1bc5872b-9601-428f-ad70-f90999085525" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=62145f3a-71c9-4f6a-8d54-e3029266b103</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=62145f3a-71c9-4f6a-8d54-e3029266b103</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A month ago I posted the results of some experimentation with the preview bits of
what was then called .NET RIA Services, Silverlight 3 and the Windows Azure with AspProvider
sample code from the Azure July 2009 CTP. That was then and much has changed.
</p>
        <p>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;displaylang=en">Windows
Azure 1.0</a> and what is now called <a href="http://silverlight.net/getstarted/riaservices/">WCF
RIA Services Beta</a> have since been released. Lot’s of great changes make using
these together with the new <a href="http://code.msdn.microsoft.com/windowsazuresamples">AspProvider
sample</a> in the “Additional C# Samples” download that some friendly readers shared
with me. With Visual Studio 2008 SP1 and SQL Server 2008 (Express if you want) and
these you’re set up to play.
</p>
        <p>
          <strong>
            <font color="#ff0000">WARNING:</font>
          </strong> They were not lying about the
WCF part when they renamed it. The default Domain Service channel is binary and they’re
using Windows Activation Service (WAS). So make sure you’re Windows Features look
something like this or you’re in for several hours of maddening error chasing.
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advnew3" border="0" alt="advnew3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_thumb.png" width="484" height="642" />
          </a>
        </p>
        <p>
After some review of the previous effort using the July 2009 CTP and RIA preview bits,
I decided starting over was the best course of action. Here’s the steps to nirvana:
</p>
        <ol>
          <li>
Create a new Silverlight Business Application called Adventure which produces Adventure.Web
application as well.</li>
          <li>
Add new CloudService project with WebRole called AdventureCloudService and WebRole1.</li>
          <li>
Copy WebRole.cs to Adventure.Web and rename namespace.</li>
          <li>
Add 3 azure refs to Adventure.Web.</li>
          <li>
In the cloud service project file, replace WebRole1 with Adventure.Web and project
guid with that from Adventure.Web. (There is probably a better way to do this.)</li>
          <li>
The node under Roles in the cloud service project shows an error. Right click it and
choose “associate” and pick Adventure.Web.</li>
          <li>
Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.</li>
          <li>
Remove WebRole1 from solution and set service project as startup.</li>
          <li>
Copy and new AspProviders project and sections from demo web.config into Adventure.Web,
changing DefaultProviderApplicationName and applicationName="Adventure".</li>
          <li>
Do the same previous steps to create/copy UserProfile class and IUserProfile with
FriendlyName property too. Added to the Models directory this time. <strong>NOTE:</strong> Be
sure to get the magic strings right in the UserProfile class or you will get unexpected
results. 
</li>
          <li>
Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel
calls which are no longer needed as I understand it. 
</li>
          <li>
Drop in the code to create the admin user if it does not already exist. 
</li>
          <li>
When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but
find the needed modification is already there. Skip this step.</li>
          <li>
Just hit F5 and error is thrown. 
</li>
        </ol>
        <p>
After some lengthy research, I discovered a bug in the AspProvider's TableStorageRoleProvider.cs.
When the RoleExists method is called and no roles have yet been created an exception
is thrown. 
</p>
        <p>
          <strong>
            <font color="#ff0000">AspProvider Fix Found</font>
            <br />
          </strong>Replace <strong>e.InnerException</strong> in line 484 in TableStorageRoleProvider.cs
with <strong>e.InnerException.InnerException</strong>. The first inner exception is
another InvalidOperationException. The second inner exception is the DataServiceClientException
we're looking for. 
</p>
        <p>
Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus
area. 
</p>
        <p>
And we’re back to par. <a href="http://www.tsjensen.com/blog/content/binary/Adventure3.zip">Download
the code here (566KB)</a>. <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=62145f3a-71c9-4f6a-8d54-e3029266b103" /></p>
      </body>
      <title>Enterprise Silverlight 3 with WCF RIA Services on Windows Azure 1.0 Part 1 Redux</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/11/24/Enterprise+Silverlight+3+With+WCF+RIA+Services+On+Windows+Azure+10+Part+1+Redux.aspx</link>
      <pubDate>Tue, 24 Nov 2009 03:48:05 GMT</pubDate>
      <description>&lt;p&gt;
A month ago I posted the results of some experimentation with the preview bits of
what was then called .NET RIA Services, Silverlight 3 and the Windows Azure with AspProvider
sample code from the Azure July 2009 CTP. That was then and much has changed.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;amp;displaylang=en"&gt;Windows
Azure 1.0&lt;/a&gt; and what is now called &lt;a href="http://silverlight.net/getstarted/riaservices/"&gt;WCF
RIA Services Beta&lt;/a&gt; have since been released. Lot’s of great changes make using
these together with the new &lt;a href="http://code.msdn.microsoft.com/windowsazuresamples"&gt;AspProvider
sample&lt;/a&gt; in the “Additional C# Samples” download that some friendly readers shared
with me. With Visual Studio 2008 SP1 and SQL Server 2008 (Express if you want) and
these you’re set up to play.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color="#ff0000"&gt;WARNING:&lt;/font&gt;&lt;/strong&gt; They were not lying about the
WCF part when they renamed it. The default Domain Service channel is binary and they’re
using Windows Activation Service (WAS). So make sure you’re Windows Features look
something like this or you’re in for several hours of maddening error chasing.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advnew3" border="0" alt="advnew3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_thumb.png" width="484" height="642"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
After some review of the previous effort using the July 2009 CTP and RIA preview bits,
I decided starting over was the best course of action. Here’s the steps to nirvana:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Create a new Silverlight Business Application called Adventure which produces Adventure.Web
application as well.&lt;/li&gt;
&lt;li&gt;
Add new CloudService project with WebRole called AdventureCloudService and WebRole1.&lt;/li&gt;
&lt;li&gt;
Copy WebRole.cs to Adventure.Web and rename namespace.&lt;/li&gt;
&lt;li&gt;
Add 3 azure refs to Adventure.Web.&lt;/li&gt;
&lt;li&gt;
In the cloud service project file, replace WebRole1 with Adventure.Web and project
guid with that from Adventure.Web. (There is probably a better way to do this.)&lt;/li&gt;
&lt;li&gt;
The node under Roles in the cloud service project shows an error. Right click it and
choose “associate” and pick Adventure.Web.&lt;/li&gt;
&lt;li&gt;
Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.&lt;/li&gt;
&lt;li&gt;
Remove WebRole1 from solution and set service project as startup.&lt;/li&gt;
&lt;li&gt;
Copy and new AspProviders project and sections from demo web.config into Adventure.Web,
changing DefaultProviderApplicationName and applicationName="Adventure".&lt;/li&gt;
&lt;li&gt;
Do the same previous steps to create/copy UserProfile class and IUserProfile with
FriendlyName property too. Added to the Models directory this time. &lt;strong&gt;NOTE:&lt;/strong&gt; Be
sure to get the magic strings right in the UserProfile class or you will get unexpected
results. 
&lt;/li&gt;
&lt;li&gt;
Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel
calls which are no longer needed as I understand it. 
&lt;/li&gt;
&lt;li&gt;
Drop in the code to create the admin user if it does not already exist. 
&lt;/li&gt;
&lt;li&gt;
When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but
find the needed modification is already there. Skip this step.&lt;/li&gt;
&lt;li&gt;
Just hit F5 and error is thrown. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
After some lengthy research, I discovered a bug in the AspProvider's TableStorageRoleProvider.cs.
When the RoleExists method is called and no roles have yet been created an exception
is thrown. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color="#ff0000"&gt;AspProvider Fix Found&lt;/font&gt;
&lt;br&gt;
&lt;/strong&gt;Replace &lt;strong&gt;e.InnerException&lt;/strong&gt; in line 484 in TableStorageRoleProvider.cs
with &lt;strong&gt;e.InnerException.InnerException&lt;/strong&gt;. The first inner exception is
another InvalidOperationException. The second inner exception is the DataServiceClientException
we're looking for. 
&lt;/p&gt;
&lt;p&gt;
Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus
area. 
&lt;p&gt;
And we’re back to par. &lt;a href="http://www.tsjensen.com/blog/content/binary/Adventure3.zip"&gt;Download
the code here (566KB)&lt;/a&gt;. &lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=62145f3a-71c9-4f6a-8d54-e3029266b103" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After spending last weekend working on and blogging about Silverlight 3 and .NET RIA
services, I decided I’d look to build out a membership, profile and role provider
that would use Windows Azure storage. Much to my delight, I stumbled into the AspProvidersDemo
code that comes with the <a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=aa40f3e2-afc5-484d-b4e9-6a5227e73590&amp;displaylang=en">Windows
Azure SDK</a> or perhaps the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=8D75D4F7-77A4-4ADF-BCE8-1B10608574BB&amp;displaylang=en">Visual
Studio 2008 Tools for Azure</a>. 
</p>
        <p>
No matter, you need them both to follow along with this post. If you have not already,
you should look at my previous post and make sure you prepare your environment for
Silverlight 3 in addition to signing up for your Azure account and installed the tools
mentioned 
</p>
        <p>
You can <a href="http://www.tsjensen.com/blog/content/binary/cloud1.zip">download
the entire solution file (434KB)</a> and skip to the momentous striking of your F5
key if you like. Or you can follow along here and blunder through this adventure as
I did. (I recommend cheating now and downloading the code.)
</p>
        <p>
Here’s the step-by-step details. I’ll try to spare the you excruciating minutiae and
keep it as exciting as possible.     
</p>
        <p>
I started by creating a standard Cloud Service application called MyFilesCloudService
with a web role called WebFilesRole. I then added a Silverlight Business Application
called Adventure. Unfortunately, this template does not allow you to select the web
role application to host the Silverlight app.
</p>
        <p>
I removed the Adventure.Web application and in the web role’s project properties added
the Silverlight app in the Silverlight Application tab. (ERROR: This turned out to
be a problem which I solved by added a throwaway standard Silverlight app to the solution,
selecting the WebFilesRole app as the host. I am still not certain why, but I’ll spare
you the grisly details of experimentation with the web.config. If you haven’t already,
this is a good place to stop and download the code.)
</p>
        <p>
I copied the AspProviders and StorageClient projects from the Azure SDK demos folder
into the solution directory and added them to the solution. I also copied the relevant
sections from the web.config for the web role and the ServiceConfiguration.cscfg and
ServiceDefinition.csdef files in cloud service project. 
</p>
        <p>
I hit F5 for kicks and get (via Event Viewer) an event 3007, “A compilation error
has occurred.” Upon further digging I realize that the profile provider is configured
to inherit it’s ProfileBase from UserProfile. The class is in the demo’s web role.
Steal that too. Here it is as added to the web role in my project:
</p>
        <pre name="code" class="brush: c-sharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;

namespace WebFilesRole
{
   public class UserProfile : ProfileBase
   {
      public static UserProfile GetUserProfile(string username)
      {
         return Create(username) as UserProfile;
      }

      public static UserProfile GetUserProfile()
      {
         return Create(Membership.GetUser().UserName) as UserProfile;
      }


      [SettingsAllowAnonymous(false)]
      public string Country
      {
         get { return base["Country"] as string; }
         set { base["Country"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public string Gender
      {
         get { return base["Gender"] as string; }
         set { base["Gender"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public int Age
      {
         get { return (int)(base["Age"]); }
         set { base["Age"] = value; }
      }
   }
}
</pre>
        <p>
I boldly hit F5 again and get this gem:
</p>
        <blockquote>
          <p>
Configuration Error 
<br />
Initialization of data service structures (tables and/or blobs) failed!<br />
The most probable reason for this is that the storage endpoints are not configured
correctly.<br />
Line 133: type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
</p>
        </blockquote>
        <p>
A little searching and googling and I learn that I need to right-click on my cloud
service application and select “Create Test Storage Tables.” I do it and bada-bing,
I get this nice dialog and Output window text:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent3" border="0" alt="advent3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_thumb.png" width="459" height="204" />
          </a>
        </p>
        <blockquote>
          <p>
DevTableGen : Generating database 'MyFilesCloudService'<br />
DevTableGen : Generating table 'Roles' for type 'Microsoft.Samples.ServiceHosting.AspProviders.RoleRow'<br />
DevTableGen : Generating table 'Sessions' for type 'Microsoft.Samples.ServiceHosting.AspProviders.SessionRow'<br />
DevTableGen : Generating table 'Membership' for type 'Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow'<br />
===== Create test storage tables succeeded =====
</p>
        </blockquote>
        <p>
Aha! I go examine my local SQL Server instance and sure enough, there’s a new DB called
MyFilesCloudService with some interesting tables. You can take at look at your own
when you’ve read far enough along here to learn to click that “Create Test Storage
Tables” magic context menu item too.
</p>
        <p>
So I experiment a little and create a couple of test tables like this:
</p>
        <pre name="code" class="brush: c-sharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Samples.ServiceHosting.StorageClient;

namespace WebFilesRole
{
   public class MyTestDataServiceContext : TableStorageDataServiceContext
   {
      public IQueryable<MyTestRow>
Roles { get { return this.CreateQuery<MyTestRow>
("MyTest"); } } } public class MyTestRow : TableStorageEntity { public string MyTestName
{ get; set; } } }
</MyTestRow></MyTestRow></pre>
        <p>
Note the nice and easy TableStorageEntity and it’s TableStorageDataServiceContext.
Just don’t make the mistake I did and forget to name the property something unique.
I tried Roles (yeah, a copy/past error) and got a nasty message like this:
</p>
        <blockquote>
          <p>
No table generated for property 'Roles' of class 'WebFilesRole.MyTestDataServiceContext'
because the name matches (or differs only in case) from the name of a previously generated
table
</p>
        </blockquote>
        <p>
I add an AppInitializer class to make sure these tables get created in the cloud when
run there. First, I add a bit of code to the Application_BeginRequest method in the
Global.asax.cs (the one I just added but didn’t tell you about).
</p>
        <pre name="code" class="brush: c-sharp;">
protected void Application_BeginRequest(object sender, EventArgs e)	
{	
   HttpApplication app = sender as HttpApplication;   
   if (app != null)   
   {   
      HttpContext context = app.Context;   
      AppInitializer.Initialize(context);   
   }   
}</pre>
        <p>
I then add the initializer class at the bottom of that same code file.
</p>
        <pre name="code" class="brush: c-sharp;">
internal static class AppInitializer
{
   static object lob = new object();
   static bool alreadyInitialized = false;
   public static void Initialize(HttpContext context)
   {
      if (alreadyInitialized) return;
      lock (lob)
      {
         if (alreadyInitialized) return;
         InitializeAppStartFirstRequest(context);
         alreadyInitialized = true;
      }
   }

   private static void InitializeAppStartFirstRequest(HttpContext context)
   {
      StorageAccountInfo account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.RoleRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.SessionRow));
      TableStorage.CreateTablesFromModel(typeof(Room));
   }
}</pre>
        <p>
I then add some test code into the Default.aspx.cs which I won’t bore you with here.
You can look at it in the downloaded solution. I got a weird error with the session
test, but after a reboot, it went away, so I’ll chalk that up to the development fabric
being a CTP.
</p>
        <p>
Now I want to get back to working Silverlight into the picture. I need to create an
admin user for my test login, so I add some code to the AppInitializer class in the
Global.asax.cs file like this:
</p>
        <pre name="code" class="brush: c-sharp;">
MembershipUser user = Membership.GetUser("admin");
if (null == user)
{
   //create admin user
   MembershipCreateStatus status = MembershipCreateStatus.Success;
   Membership.CreateUser("admin", "admin", "admin@admin.com", "admin-admin", "admin", 
      true, Guid.NewGuid(), out status);

   //add admin user to admin role
   if (status == MembershipCreateStatus.Success)
   {
      if (!Roles.RoleExists("admin"))
      {
         Roles.CreateRole("admin");
      }
      Roles.AddUserToRole("admin", "admin");
   }

   //add profile data to admin user
   UserProfile profile = UserProfile.Create("admin") as UserProfile;
   profile.Age = 40;    //not my true age
   profile.Country = "US";
   profile.Gender = "M";
   profile.Save();
}</pre>
        <p>
I look at the UserProfile class and know that the DomainService’s User class needs
the same properties in order for the Silverlight RiaContext to know about them. I
discovered in the metadata code the following comments in the UpdateUser method of
the  System.Web.Ria.ApplicationServices.AuthenticationBase&lt;T&gt; base class
used for the AuthenticationService domain service class:
</p>
        <pre name="code" class="brush: c-sharp;">
// Remarks:
//     By default, the user is persisted to the System.Web.Profile.ProfileBase.
//     In writing the user to the profile, the provider copies each property in
//     T into the corresponding value in the profile. This behavior can be tailored
//     by marking specified properties with the System.Web.Ria.ApplicationServices.ProfileUsageAttribute.</pre>
        <p>
I know now that I want the UserProfile and the User classes to have the same profile
properties, so I add an interface above the UserProfile class like this:
</p>
        <pre name="code" class="brush: c-sharp;">
public interface IUserProfile	
{	
   string Country { get; set; }   
   string Gender { get; set; }   
   int Age { get; set; }   
}</pre>
        <p>
And then add the same properties found in UserProfile to the User class in the AuthenticationService.cs
file as follows:
</p>
        <pre name="code" class="brush: c-sharp;">
public class User : UserBase, IUserProfile   
{   
   // NOTE: Profile properties can be added for use in Silverlight application.   
   // To enable profiles, edit the appropriate section of web.config file.   
   
   // public string MyProfileProperty { get; set; }   
   
   public string Country { get; set; }   
   
   public string Gender { get; set; }   
   
   public int Age { get; set; }   
}</pre>
        <p>
I try to run it and get the following error on the Silverlight app when I try to login
using admin/admin: "The specified resource was not found." A little digging reveals
that I need two things: first, some additions to the web.config file that I was missing,
and second, the ServiceDefinition.csdef had to have it’s enableNativeCodeExecution
set to true. Here’s the pieces:
</p>
        <pre name="code" class="brush: xml;">
&lt;!-- handlers and httpHandlers sections require the following additions --&gt;
&lt;handlers&gt;
   &lt;add name="DataService" verb="GET,POST" path="DataService.axd" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;		
&lt;/handlers&gt;

&lt;httpHandlers&gt;
   &lt;add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/&gt;		
&lt;/httpHandlers&gt;

&lt;!-- the ServiceDefinition.csdef gets the enableNativeCodeExecution set to true --&gt;
&lt;WebRole name="WebFilesRole" enableNativeCodeExecution="true"&gt;</pre>
        <p>
Once those changes were made, I was able to run the Silverlight application, login
using admin/admin and logout. Now one more item on the agenda for this post. I want
to see the profile information we added in the AppInitializer code. So I modify the
LoginControl.xaml and LoginControl.xaml.cs as follows.
</p>
        <pre name="code" class="brush: xml;">
&lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
   &lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
   &lt;TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
      &lt;TextBlock Text="" x:Name="ProfileText" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
   &lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;
&lt;/StackPanel&gt;</pre>
        <p>
With the code behind changed like this:
</p>
        <pre name="code" class="brush: c-sharp;">
private void UpdateLoginState()	
{	
   if (RiaContext.Current.User.AuthenticationType == "Windows")   
   {   
      VisualStateManager.GoToState(this, "windowsAuth", true);   
   }   
   else //User.AuthenticationType == "Forms"   
   {   
      VisualStateManager.GoToState(this,    
         RiaContext.Current.User.IsAuthenticated ? "loggedIn" : "loggedOut", true);   
   
      if (RiaContext.Current.User.IsAuthenticated)   
      {   
         this.ProfileText.Text = string.Format("age:{0}, country:{1}, gender:{2}",    
            RiaContext.Current.User.Age,    
            RiaContext.Current.User.Country,    
            RiaContext.Current.User.Gender);   
      }   
   }
}</pre>
        <p>
Now when I login, I get to look at something like this:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent8" border="0" alt="advent8" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_thumb.png" width="447" height="162" />
          </a>
        </p>
        <p>
Cool. In Part 2, I’ll modify the UserProfile to capture the data I want to keep in
my Adventure application and complete the user registration changes to the Silverlight
application as well as clean up and prepare the app for some real application development
in follow-on posts.
</p>
        <p>
If you have any questions or ways to do this better, I’d love to hear from you.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f" />
      </body>
      <title>Building Enterprise Applications with Silverlight 3, .NET RIA Services and Windows Azure Part 1</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/10/19/Building+Enterprise+Applications+With+Silverlight+3+NET+RIA+Services+And+Windows+Azure+Part+1.aspx</link>
      <pubDate>Mon, 19 Oct 2009 01:58:29 GMT</pubDate>
      <description>&lt;p&gt;
After spending last weekend working on and blogging about Silverlight 3 and .NET RIA
services, I decided I’d look to build out a membership, profile and role provider
that would use Windows Azure storage. Much to my delight, I stumbled into the AspProvidersDemo
code that comes with the &lt;a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=aa40f3e2-afc5-484d-b4e9-6a5227e73590&amp;amp;displaylang=en"&gt;Windows
Azure SDK&lt;/a&gt; or perhaps the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=8D75D4F7-77A4-4ADF-BCE8-1B10608574BB&amp;amp;displaylang=en"&gt;Visual
Studio 2008 Tools for Azure&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
No matter, you need them both to follow along with this post. If you have not already,
you should look at my previous post and make sure you prepare your environment for
Silverlight 3 in addition to signing up for your Azure account and installed the tools
mentioned 
&lt;/p&gt;
&lt;p&gt;
You can &lt;a href="http://www.tsjensen.com/blog/content/binary/cloud1.zip"&gt;download
the entire solution file (434KB)&lt;/a&gt; and skip to the momentous striking of your F5
key if you like. Or you can follow along here and blunder through this adventure as
I did. (I recommend cheating now and downloading the code.)
&lt;/p&gt;
&lt;p&gt;
Here’s the step-by-step details. I’ll try to spare the you excruciating minutiae and
keep it as exciting as possible.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I started by creating a standard Cloud Service application called MyFilesCloudService
with a web role called WebFilesRole. I then added a Silverlight Business Application
called Adventure. Unfortunately, this template does not allow you to select the web
role application to host the Silverlight app.
&lt;/p&gt;
&lt;p&gt;
I removed the Adventure.Web application and in the web role’s project properties added
the Silverlight app in the Silverlight Application tab. (ERROR: This turned out to
be a problem which I solved by added a throwaway standard Silverlight app to the solution,
selecting the WebFilesRole app as the host. I am still not certain why, but I’ll spare
you the grisly details of experimentation with the web.config. If you haven’t already,
this is a good place to stop and download the code.)
&lt;/p&gt;
&lt;p&gt;
I copied the AspProviders and StorageClient projects from the Azure SDK demos folder
into the solution directory and added them to the solution. I also copied the relevant
sections from the web.config for the web role and the ServiceConfiguration.cscfg and
ServiceDefinition.csdef files in cloud service project. 
&lt;/p&gt;
&lt;p&gt;
I hit F5 for kicks and get (via Event Viewer) an event 3007, “A compilation error
has occurred.” Upon further digging I realize that the profile provider is configured
to inherit it’s ProfileBase from UserProfile. The class is in the demo’s web role.
Steal that too. Here it is as added to the web role in my project:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;

namespace WebFilesRole
{
   public class UserProfile : ProfileBase
   {
      public static UserProfile GetUserProfile(string username)
      {
         return Create(username) as UserProfile;
      }

      public static UserProfile GetUserProfile()
      {
         return Create(Membership.GetUser().UserName) as UserProfile;
      }


      [SettingsAllowAnonymous(false)]
      public string Country
      {
         get { return base["Country"] as string; }
         set { base["Country"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public string Gender
      {
         get { return base["Gender"] as string; }
         set { base["Gender"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public int Age
      {
         get { return (int)(base["Age"]); }
         set { base["Age"] = value; }
      }
   }
}
&lt;/pre&gt;
&lt;p&gt;
I boldly hit F5 again and get this gem:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Configuration Error 
&lt;br&gt;
Initialization of data service structures (tables and/or blobs) failed!&lt;br&gt;
The most probable reason for this is that the storage endpoints are not configured
correctly.&lt;br&gt;
Line 133: type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
A little searching and googling and I learn that I need to right-click on my cloud
service application and select “Create Test Storage Tables.” I do it and bada-bing,
I get this nice dialog and Output window text:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent3" border="0" alt="advent3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_thumb.png" width="459" height="204"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
DevTableGen : Generating database 'MyFilesCloudService'&lt;br&gt;
DevTableGen : Generating table 'Roles' for type 'Microsoft.Samples.ServiceHosting.AspProviders.RoleRow'&lt;br&gt;
DevTableGen : Generating table 'Sessions' for type 'Microsoft.Samples.ServiceHosting.AspProviders.SessionRow'&lt;br&gt;
DevTableGen : Generating table 'Membership' for type 'Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow'&lt;br&gt;
===== Create test storage tables succeeded =====
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Aha! I go examine my local SQL Server instance and sure enough, there’s a new DB called
MyFilesCloudService with some interesting tables. You can take at look at your own
when you’ve read far enough along here to learn to click that “Create Test Storage
Tables” magic context menu item too.
&lt;/p&gt;
&lt;p&gt;
So I experiment a little and create a couple of test tables like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Samples.ServiceHosting.StorageClient;

namespace WebFilesRole
{
   public class MyTestDataServiceContext : TableStorageDataServiceContext
   {
      public IQueryable&lt;MyTestRow&gt;
Roles { get { return this.CreateQuery&lt;MyTestRow&gt;
("MyTest"); } } } public class MyTestRow : TableStorageEntity { public string MyTestName
{ get; set; } } }
&lt;/pre&gt;
&lt;p&gt;
Note the nice and easy TableStorageEntity and it’s TableStorageDataServiceContext.
Just don’t make the mistake I did and forget to name the property something unique.
I tried Roles (yeah, a copy/past error) and got a nasty message like this:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
No table generated for property 'Roles' of class 'WebFilesRole.MyTestDataServiceContext'
because the name matches (or differs only in case) from the name of a previously generated
table
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I add an AppInitializer class to make sure these tables get created in the cloud when
run there. First, I add a bit of code to the Application_BeginRequest method in the
Global.asax.cs (the one I just added but didn’t tell you about).
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
protected void Application_BeginRequest(object sender, EventArgs e)	
{	
   HttpApplication app = sender as HttpApplication;   
   if (app != null)   
   {   
      HttpContext context = app.Context;   
      AppInitializer.Initialize(context);   
   }   
}&lt;/pre&gt;
&lt;p&gt;
I then add the initializer class at the bottom of that same code file.
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
internal static class AppInitializer
{
   static object lob = new object();
   static bool alreadyInitialized = false;
   public static void Initialize(HttpContext context)
   {
      if (alreadyInitialized) return;
      lock (lob)
      {
         if (alreadyInitialized) return;
         InitializeAppStartFirstRequest(context);
         alreadyInitialized = true;
      }
   }

   private static void InitializeAppStartFirstRequest(HttpContext context)
   {
      StorageAccountInfo account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.RoleRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.SessionRow));
      TableStorage.CreateTablesFromModel(typeof(Room));
   }
}&lt;/pre&gt;
&lt;p&gt;
I then add some test code into the Default.aspx.cs which I won’t bore you with here.
You can look at it in the downloaded solution. I got a weird error with the session
test, but after a reboot, it went away, so I’ll chalk that up to the development fabric
being a CTP.
&lt;/p&gt;
&lt;p&gt;
Now I want to get back to working Silverlight into the picture. I need to create an
admin user for my test login, so I add some code to the AppInitializer class in the
Global.asax.cs file like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
MembershipUser user = Membership.GetUser("admin");
if (null == user)
{
   //create admin user
   MembershipCreateStatus status = MembershipCreateStatus.Success;
   Membership.CreateUser("admin", "admin", "admin@admin.com", "admin-admin", "admin", 
      true, Guid.NewGuid(), out status);

   //add admin user to admin role
   if (status == MembershipCreateStatus.Success)
   {
      if (!Roles.RoleExists("admin"))
      {
         Roles.CreateRole("admin");
      }
      Roles.AddUserToRole("admin", "admin");
   }

   //add profile data to admin user
   UserProfile profile = UserProfile.Create("admin") as UserProfile;
   profile.Age = 40;    //not my true age
   profile.Country = "US";
   profile.Gender = "M";
   profile.Save();
}&lt;/pre&gt;
&lt;p&gt;
I look at the UserProfile class and know that the DomainService’s User class needs
the same properties in order for the Silverlight RiaContext to know about them. I
discovered in the metadata code the following comments in the UpdateUser method of
the&amp;nbsp; System.Web.Ria.ApplicationServices.AuthenticationBase&amp;lt;T&amp;gt; base class
used for the AuthenticationService domain service class:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
// Remarks:
//     By default, the user is persisted to the System.Web.Profile.ProfileBase.
//     In writing the user to the profile, the provider copies each property in
//     T into the corresponding value in the profile. This behavior can be tailored
//     by marking specified properties with the System.Web.Ria.ApplicationServices.ProfileUsageAttribute.&lt;/pre&gt;
&lt;p&gt;
I know now that I want the UserProfile and the User classes to have the same profile
properties, so I add an interface above the UserProfile class like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
public interface IUserProfile	
{	
   string Country { get; set; }   
   string Gender { get; set; }   
   int Age { get; set; }   
}&lt;/pre&gt;
&lt;p&gt;
And then add the same properties found in UserProfile to the User class in the AuthenticationService.cs
file as follows:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
public class User : UserBase, IUserProfile   
{   
   // NOTE: Profile properties can be added for use in Silverlight application.   
   // To enable profiles, edit the appropriate section of web.config file.   
   
   // public string MyProfileProperty { get; set; }   
   
   public string Country { get; set; }   
   
   public string Gender { get; set; }   
   
   public int Age { get; set; }   
}&lt;/pre&gt;
&lt;p&gt;
I try to run it and get the following error on the Silverlight app when I try to login
using admin/admin: "The specified resource was not found." A little digging reveals
that I need two things: first, some additions to the web.config file that I was missing,
and second, the ServiceDefinition.csdef had to have it’s enableNativeCodeExecution
set to true. Here’s the pieces:
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;!-- handlers and httpHandlers sections require the following additions --&gt;
&amp;lt;handlers&gt;
   &amp;lt;add name="DataService" verb="GET,POST" path="DataService.axd" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;		
&amp;lt;/handlers&gt;

&amp;lt;httpHandlers&gt;
   &amp;lt;add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/&gt;		
&amp;lt;/httpHandlers&gt;

&amp;lt;!-- the ServiceDefinition.csdef gets the enableNativeCodeExecution set to true --&gt;
&amp;lt;WebRole name="WebFilesRole" enableNativeCodeExecution="true"&gt;&lt;/pre&gt;
&lt;p&gt;
Once those changes were made, I was able to run the Silverlight application, login
using admin/admin and logout. Now one more item on the agenda for this post. I want
to see the profile information we added in the AppInitializer code. So I modify the
LoginControl.xaml and LoginControl.xaml.cs as follows.
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
   &amp;lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
   &amp;lt;TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
      &amp;lt;TextBlock Text="" x:Name="ProfileText" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
   &amp;lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;
&amp;lt;/StackPanel&gt;&lt;/pre&gt;
&lt;p&gt;
With the code behind changed like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
private void UpdateLoginState()	
{	
   if (RiaContext.Current.User.AuthenticationType == "Windows")   
   {   
      VisualStateManager.GoToState(this, "windowsAuth", true);   
   }   
   else //User.AuthenticationType == "Forms"   
   {   
      VisualStateManager.GoToState(this,    
         RiaContext.Current.User.IsAuthenticated ? "loggedIn" : "loggedOut", true);   
   
      if (RiaContext.Current.User.IsAuthenticated)   
      {   
         this.ProfileText.Text = string.Format("age:{0}, country:{1}, gender:{2}",    
            RiaContext.Current.User.Age,    
            RiaContext.Current.User.Country,    
            RiaContext.Current.User.Gender);   
      }   
   }
}&lt;/pre&gt;
&lt;p&gt;
Now when I login, I get to look at something like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent8" border="0" alt="advent8" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_thumb.png" width="447" height="162"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Cool. In Part 2, I’ll modify the UserProfile to capture the data I want to keep in
my Adventure application and complete the user registration changes to the Silverlight
application as well as clean up and prepare the app for some real application development
in follow-on posts.
&lt;/p&gt;
&lt;p&gt;
If you have any questions or ways to do this better, I’d love to hear from you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
  </channel>
</rss>