ASP.Net MVC on Windows Azure with Providers

[For more recent information on using ASP.NET MVC with Windows Azure please see this post.]

Before you get started with ASP.Net MVC and Windows Azure – please install this hotfix.

Were you wondering why the sample project I got from Phil attached to my post, ASP.Net MVC on Windows Azure, didn't include the sample Windows Azure ASP.Net providers?

The answer is that we wanted to get something out early that would unblock folks from trying out the MVC on Windows Azure scenario.  That sample solution accomplished that.

We were also working out a problem we were seeing when using those providers with MVC.  The problem was that we would get a timeout after logging in or creating a new account when running on Windows Azure -- a problem you won't see when running locally against the Development Fabric.

Luckily, Phil pointed me to a workaround which I've now verified solves this problem. (the fix is now in MVC).

I tend to get pinged from time to time about issues with RequestURL so I’ll give a pointer to a post to David’s blog that talks about that.

This post will cover augmenting the existing "MVC on Windows Azure sample" with membership, role and session state providers as well as the workaround that ensures the sample works when you run on Windows Azure.

It is again important to note that using ASP.Net MVC on Windows Azure is still a preview.

The sample code that goes along with this code is on the MSDN Code Gallery MVCCloudService and does not include the sample projects from the Windows Azure SDK, please follow the instruction below for adding and referencing them. (when you first load the project it will complain that the sample projects are missing)

Starting with the sample project attached to my last post, the first thing to do is to add the AspProviders and the StorageClient projects found in the Windows Azure SDK samples to the solution.

These sample projects are found in the SDK install folder (C:\Program Files\Windows Azure SDK\v1.0 by default), where you'll see a zip file (samples.zip).  Copy this file to a writeable (i.e. not in Program Files) location and unzip it.

Right click on the Solution node in Solution Explorer -> Add -> Existing Project:

image

Navigate to the directory where you unzipped the Windows Azure SDK samples, AspProviders\Lib and select AspProviders.csproj:

image

Do the same to add the StorageClient.csproj project from StorageClient\Lib:

image

Then add project references to both of those projects by right clicking on the reference node in the CloudService1_WebRole project and selecting "Add Reference...", choosing the Projects Tab, selected both AspProviders and StorageClient projects and hitting "OK".

image

Let's now add the Service Definition and Service Configuration settings and values needed to access the Windows Azure Storage Services by by adding the following code to the Service Definition and Service Configuration files found in the Cloud Service project.

The settings below are setup for the local Development Storage case.

Note: When switching over to the *.core.windows.net endpoints, you'll have to use the https addresses (i.e. https://blob.core.windows.net) otherwise the providers will throw an exception.  Alternatively you could set allowInsecureRemoteEndpoints to true -- however that is not recommended.

The definitions in ServiceDefinition.csdef:

 <ConfigurationSettings>
    <Setting name="AccountName"/>
    <Setting name="AccountSharedKey"/>
    <Setting name="BlobStorageEndpoint"/>
    <Setting name="QueueStorageEndpoint"/>
    <Setting name="TableStorageEndpoint"/>
    <Setting name="allowInsecureRemoteEndpoints"/>
</ConfigurationSettings>

The Values in ServiceConfiguration.cscfg:

 <Setting name="AccountName" value="devstoreaccount1"/>
<Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
<Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
<Setting name="QueueStorageEndpoint" value = "https://127.0.0.1:10001"/>
<Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
<Setting name="allowInsecureRemoteEndpoints" value=""/>

The providers also have settings to specify the name of the table for storing membership, role and session related data.  Note that as the comment indicates, the values below are the only values that will work in the Development Storage case. 

In the MVCWebrole web.config, change <appSettings/> to the following:

 <appSettings>
    <!-- provider configuration -->
    <!-- When using the local development table storage service only the default values given
     below will work for the tables (Membership, Roles and Sessions) since these are the names
     of the properties on the DataServiceContext class -->
    <add key = "DefaultMembershipTableName" value="Membership"/>
    <add key = "DefaultRoleTableName" value="Roles"/>
    <add key = "DefaultSessionTableName" value="Sessions"/>
    <add key = "DefaultProviderApplicationName" value="MvcCloudService"/>
    <add key = "DefaultSessionContainerName"/>
</appSettings>

The following connection string for SQL can be removed:

 <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>

We'll now add the providers, via the MVCWebRole web.config file (remove the existing SQL Server ones).  First the membership provider:

     <membership defaultProvider="TableStorageMembershipProvider" userIsOnlineTimeWindow = "20">
      <providers>
        <clear/>

        <add name="TableStorageMembershipProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageMembershipProvider"
             description="Membership provider using table storage"
             applicationName="MvcCloudService"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false"
             minRequiredPasswordLength="1"
             minRequiredNonalphanumericCharacters="0"
             requiresUniqueEmail="true"
             passwordFormat="Hashed"
                />

      </providers>
    </membership>

Role Manager provider:

     <roleManager enabled="true" defaultProvider="TableStorageRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="30"
                 cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration = "true"
                 cookieProtection="All" >
      <providers>
        <clear/>
        <add name="TableStorageRoleProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageRoleProvider"
             description="Role provider using table storage"
             applicationName="MvcCloudService"
                />
      </providers>
    </roleManager>

and the session state provider:

     <sessionState mode="Custom" customProvider="TableStorageSessionStateProvider">
      <providers>
        <clear />
        <add name="TableStorageSessionStateProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
             applicationName="MvcCloudService"
             />
      </providers>
    </sessionState>

You can consult the AspProvidersDemo project in the Windows Azure SDK samples as well. 

Note: there is also a profile provider which would be added in the same manner.

Before running, right click on the Cloud Service project node in Solution Explorer and select "Create Test Storage Tables".  (For more information on creating test storage tables, see this article)

image

And there you have it – ASP.Net MVC RC2 running on Windows Azure.

Comments

  • Anonymous
    November 10, 2008
    Jim just posted an update to his ASP.Net MVC on Windows Azure sample -- which includes plugging in the

  • Anonymous
    November 10, 2008
    I was wondering about the providers. This is excellent. Now to integrate this with the rest of the setup :)

  • Anonymous
    November 10, 2008
    Guys, you have just beaten me. I submitted an article on making of Membership provider for the cloud last night to the DotNetSlackers.com editors. Anyway, I'm satisfied because it's your day job at Microsoft, and it's my night passion after work. :-) Tanzim Saqib W: www.TanzimSaqib.com

  • Anonymous
    November 10, 2008
    Today’s buzz has a lot more “look what I can do with Azure” than “what is Windows Azure” buzz. It’s also

  • Anonymous
    November 11, 2008
    Cloudship: Membership Provider for the Cloud: http://dotnetslackers.com/articles/aspnet/Azure-Cloudship-Membership-Provider-for-the-Cloud.aspx

  • Anonymous
    January 06, 2009
    So I've had a couple of questions about hosting web services (SOAP style services in the form of *.aspx

  • Anonymous
    January 10, 2009
    Thank you for submitting this cool story - Trackback from DotNetShoutout

  • Anonymous
    February 15, 2009
    The comment has been removed

  • Anonymous
    February 15, 2009
    Update: Even before starting these steps, I can crash VS by opening Register.aspx, or presumably any other file.  I'm just using your AspNetMvcCloudService zip file.  Thoughts?  Plain old MVC.NET projects work fine.   P.S.  I'm on the MVC RC.

  • Anonymous
    February 15, 2009
    The crash is due to a known issue in the CLR that affects more than just this scenario -- the CLR team is working on a patch. The issue presents itself (or not) depending on order in which the MVC, ASP.Net and System.Core assemblies load - taking a different path through the product that loads these assemblies in a different order can resolve the problem. Sorry for the inconvenience. P.S. We're working on a better project creation story for MVC projects which is dependent on having supported Windows Azure ASP.Net Providers.  Unfortunately, we cannot share a time frame in which this will happen.  It is on out list.

  • Anonymous
    February 15, 2009
    I've received some comments as well as have been contacted by a couple of customers about an issue they

  • Anonymous
    February 24, 2009
    We're really starting to get a solid set of resources out there for Windows Azure developers! Cloud Computing

  • Anonymous
    March 03, 2009
    If you’re encountered an issue where Visual Studio 2008 SP1 crashes silently whenever you try to open a web form or master page (which by default will open the design view), there is a hotfix that will likely solve the problem.&#160; I ran into this recently

  • Anonymous
    March 08, 2009
    ASP.Net MVC RC2 released a few days back and I've already gotten a number of requests to update the MVC

  • Anonymous
    March 16, 2009
    上个礼拜,我的Azure邀请码终于到了,小兴奋了一把,于是马上去注册账号,并成功部署了一个网站到Azure上。 由于最近在学习Asp.NetMvc框架,于是就想部署一个Mvc应用到Azure上,本...

  • Anonymous
    April 20, 2009
    开头(有点离题了,原谅!)之前我就像某人说的那样,I’mnotquiteacloudguy,但是后来看了各式各样的演示,认识了CloudProject的构成,以及Mix09里面...

  • Anonymous
    April 20, 2009
    本文叙述了本人怎么将默认的 MVC 应用程序发布到云端,并给出了一些相关的文章和注意事项以及自己的想法。

  • Anonymous
    April 20, 2009
    本文叙述了本人怎么将默认的 MVC 应用程序发布到云端,并给出了一些相关的文章和注意事项以及自己的想法。

  • Anonymous
    August 07, 2009
    This code:    <sessionState mode="Custom" customProvider="TableStorageSessionStateProvider">      <providers>        <clear />        <add name="TableStorageSessionStateProvider"             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"             applicationName="MvcCloudService"             />      </providers>    </sessionState> produces an error "Das applicationName attribut wurde nicht deklariert" which I translate as "The applicationName attrubute has not been declared." Furthermore the initialize crashes with an exeption for which no details are provided. Strange things are happening ....