(Silverlight BusinessApplication , Membership on Azure) => To Map || Not To Map

We owe Alonzo Church for this one:

    WebContext.Current.Authentication.LoggedIn += (se, ev) =>
    {
       Link2.Visibility = Visibility.Visible;
    };

    WebContext.Current.Authentication.LoggedOut += (se, ev) =>
    {
        Link2.Visibility = Visibility.Collapsed;
    };

The λ calculus “goes to” Lambda Expressions now in C#, turning mere programmers into logicians. We share in the bounty of Alonzo’s intellect in some remote fashion. Likely others understand this functional proof apparatus, but for me it’s a mechanical thing. Put this here and that there, slyly kicking an answer into existence. Is a view link visible or is it not?

Here we are not concerned with “the what” of a map but a small preliminary question, “whether to map at all?”

Azure provides a lot of cloud for the money. Between SQL Azure, blob storage, and hosted services, both web and worker roles, there are a lot of very useful resources. All, except SQL Azure, currently include built in scaling and replication. Azure SQL Server scaling is still awaiting the release of federation at some point in the future.

Visual Studio 2010 adds a Cloud toolkit with template ready services (not to be confused with “shovel ready”). One template that is interesting is the ASP .NET template combined with an Azure hosted Web Role service. The usefulness here is the full ASP .NET authentication and profile capability. If you need simple authentication, profile, and registration built on the ASP .NET model it is all here.

The goal then is to leverage the resourceful templates of ASP .NET authentication, modify this to a Silverlight version (which implies a Bing Map Control is in the future, along with some nifty transition graphics), and finally deploy to Azure.

And now for the recipe

authentication screen shot
Fig1 – open a new VS2010 project using the Cloud template

authentication screen shot
Fig2 – add an ASP .NET Web Role

authentication screen shot
Fig3 – click run to open in local development fabric with login and registration

This is helpful and works fine in a local dev fabric.

Now on to Azure:

First create a Storage Account and a Hosted Service.

authentication screen shot
Fig4 – Storage Account for use in publishing and diagnostics logs

authentication screen shot
Fig5 – Azure control manager

authentication screen shot
Fig6 – create a SQL Azure instance to hold the aspnetdb

Now using VS2010 publish the brand new ASP .NET web role to the new Azure account.

Problem 1
However, publish to Azure and you will immediately face a couple of problems. First, the published Azure service is a Web Role not a VM, which means there is no local SQL Server accessible for attaching a default aspnetdb. SQL Azure is in its own separate instance. You will need to manually create the aspnetdb Database on a SQL Azure instance and then provide a connection string to this new SQL Azure in the Web Role.

Microsoft provides sql scripts adapted for providing this to SQL Azure:http://code.msdn.microsoft.com/KB2006191

Running these scripts in your Azure DB will create the following membership database and tables:

authentication screen shot
Fig7 – aspnetdb SQL Azure database

Since I like Silverlight better it’s probably time to dump the plain Jane ASP .NET in favor of the Silverlight Navigation version. Silverlight provides animated fades and flips to which most of us are already unconsciously accustomed.

In Visual Studio add a new project from the Silverlight templates. The Silverlight Business Application is the one with membership.

authentication screen shot
Fig8 – Silverlight Business Application

We are now swapping out the old ASP .NET Cloud Web Role with a Silverlight BusinessApplication1.Web

Step 1
Add reference assemblies WindowsAzure Diagnostic, ServiceRuntime, and StorageClient to BusinessApplication1.Web

Step 2
Copy WebRole1 WebRole.cs to BusinessApplication1.Web and correct namespace

Step 3
CloudService1 Roles right click to add Role in solution – BusinessApplication.Web
(Optional remove WebRole1 from Roles and remove WebRole project since it is no longer needed)

Step 4
Add a DiagnosticsConnectionString property to the Roles/BusinessApplication1.Web role that points to the Azure blob storage. Now we can add a DiagnosticMonitor and trace logging to the WebRole.cs

Step 5
Open BusinessApplication1.Web web.config, add connection string pointed at SQL Azure aspnetdb and a set of ApplicationServices:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="system.serviceModel">
      <section name="domainServices"
type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection,
 System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication"
requirePermission="false" />
    </sectionGroup>
  </configSections>
    <connectionStrings>
        <remove name="LocalSqlServer"/>
        <add name="ApplicationServices" connectionString="Server=tcp:<SqlAzure
server>.database.windows.net;Database=aspnetdb;User
 ID=<username>;Password=<password>;Trusted_Connection=False;Encrypt=True;"
 providerName="System.Data.SqlClient" />
    </connectionStrings>


  <system.web>
    <httpModules>
      <add name="DomainServiceModule"
 type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule,
 System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral,
 PublicKeyToken=31BF3856AD364E35" />
    </httpModules>
    <compilation debug="true" targetFramework="4.0" />


    <authentication mode="Forms">
      <forms name=".BusinessApplication1_ASPXAUTH" />
    </authentication>

      <membership defaultProvider="AspNetSqlMembershipProvider">
          <providers>
              <clear/>
              <add name="AspNetSqlMembershipProvider"
 type="System.Web.Security.SqlMembershipProvider"
connectionStringName="ApplicationServices"
                   enablePasswordRetrieval="false" enablePasswordReset="true"
 requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
                   maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6"
 minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
                   applicationName="/" />
          </providers>
      </membership>

      <profile defaultProvider="AspNetSqlProfileProvider">
          <providers>
              <clear/>
              <add name="AspNetSqlProfileProvider"
 type="System.Web.Profile.SqlProfileProvider"
 connectionStringName="ApplicationServices" applicationName="/"/>
          </providers>
          <properties>
              <add name="FriendlyName"/>
          </properties>
      </profile>

      <roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
          <providers>
              <clear/>
              <add name="AspNetSqlRoleProvider"
 type="System.Web.Security.SqlRoleProvider"
 connectionStringName="ApplicationServices" applicationName="/" />
              <add name="AspNetWindowsTokenRoleProvider"
type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
          </providers>
      </roleManager>
  

  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="DomainServiceModule" preCondition="managedHandler"
          type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule
, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral,
 PublicKeyToken=31AS3856AD234E35" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
 multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

Now we can publish our updated Silverlight Web Role to Azure.

authentication screen shot
Fig9 – publish to Azure

However, this brings us to problem 2

It turns out that there are a couple of assemblies that are missing from Azure’s OS but required for our Silverlight membership BusinessApplication. When an assembly is missing publish will continue cycling between initializing and stop without ever giving a reason for the endless loop.

When this happens I know to start looking at the assembly dlls. Unfortunately they are numerous. Without a message indicating which is at fault we are reduced to trial and error. Obviously the turnaround on publish to Azure is not incredibly fast. Debug cycles will take five to ten minutes so this elimination process is tedious. However, I spent an afternoon on this and can save you some time. The trick assemblies are:
    System.ServiceModel.DomainServices.Hosting
    System.ServiceModel.DomainServices.Server

To fix this problem:
Open references under BusinessApplication1.Web and click on the above two assemblies. Then go to properties “Copy Local” which must be set to True. This means that a publish to Azure will also copy these two missing assemblies from your local VS2010 environment up to Azure and publish will eventually run as expected.

The publish process then brings us to this:

authentication screen shot
Fig10 – Login

And this:

authentication screen shot
Fig11 – Register

That in turn allows the Alonzo λ magic:

            WebContext.Current.Authentication.LoggedIn += (se, ev) =>
            {
                Link2.Visibility = Visibility.Visible;
            };

Summary:

Well it works, maybe not as easily as one would expect for a Cloud template.

This entry was posted in Uncategorized by admin. Bookmark the permalink.

Comments are closed.