Moving MVC Session State In Azure

This article is for developers who are planning to move their MVC application to an Azure environment. This will also work as an alternative of default SQL Server session state in an MVC application.
Why we need a new approach
To host application in Azure, we can't go with default Inproc and StateServer. There are a few options available in Azure for the same.
  1. Table Storage (We can also go with this approach but it will need extra cost)
  2. Windows Azure Caching (This is the fastest one but it is very costly)
  3. SQL Azure
I deployed the application with SQL Server mode. It was working fine on local servers but now it is giving me an error.

It needs ASP.NET version 2.0 session state on Azure environment or it needs some work around on it. Also, it needs a separate service (web job) to clear the expired sessions.
But, I found a better solution for it.   


So, after searching, I planned to use ASP.NET Universal Providers. You can install it through the NuGet Package Manager. It is very easy to use. It provides other features as well, but I will only focus on the session state. 

Steps to follow

So, you need to follow the below steps in order to implement ASP.NET Universal Providers in your MVC application. I am assuming, you already have a working MVC application.
Open Package Manager Console.

In Visual Studio, go to View -> Other Windows -> Package Manager console
Enter the following command in the command window.
  1. Install-Package System.Web.Providers -Version 1.2.0   
 It will install 3 packages in your application.
  • System.Web.Providers.1.2.0
  • Microsoft.AspNet.Providers.Core.1.0.0
  • Microsoft.AspNet.Providers.1.1.0 
Go to web.config
In web.config, you will see that the following highlighted lines have been added.
  1. <connectionStrings>  
  2.    <add name="YouApplicationConnectionString" connectionString="yourapplicationconnectionstring" providerName="System.Data.SqlClient" />  
  3.    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-AzureSampleApp-20170614050859;Integrated Security=SSPI" />  
  4.  </connectionStrings>  
And, this code is added inside <system.web> tag.
  1. <profile defaultProvider="DefaultProfileProvider">  
  2.       <providers>  
  3.         <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />  
  4.       </providers>  
  5.     </profile>  
  6.     <membership defaultProvider="DefaultMembershipProvider">  
  7.       <providers>  
  8.         <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />  
  9.       </providers>  
  10.     </membership>  
  11.     <roleManager defaultProvider="DefaultRoleProvider">  
  12.       <providers>  
  13.         <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />  
  14.       </providers>  
  15.     </roleManager>  
  16.     <!--  
  17.             If you are deploying to a cloud environment that has multiple web server instances,  
  18.             you should change session state mode from "InProc" to "Custom". In addition,  
  19.             change the connection string named "DefaultConnection" to connect to an instance  
  20.             of SQL Server (including SQL Azure and SQL  Compact) instead of to SQL Server Express.  
  21.       -->  
  22.     <sessionState mode="InProc" customProvider="DefaultSessionProvider">  
  23.       <providers>  
  24.         <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />  
  25.       </providers>  
  26.     </sessionState>  
Changes required in web.config file

Inside <system.web>, remove all the newly added tags except <sessionState> and update this tag as -
  1. <sessionState mode="Custom" customProvider="DefaultSessionProvider" timeout="30" >        
  2.       <providers>  
  3.         <clear/>  
  4.         <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="SQLAzureSession" />  
  5.       </providers>  
  6. </sessionState>  
Also, update the <connectionstrings> tag.
  1. <connectionStrings>    
  2.    <add name="YouApplicationConnectionString" connectionString="yourapplicationconnectionstring" providerName="System.Data.SqlClient" />   
  3.    <add name="SQLAzureSession" providerName="System.Data.SqlClient" connectionString="yourazuredatabaseconnectionstring" />    
  4. </connectionStrings>    
You can use both the connection strings as same or use only one connection string. This Provider creates only 1 table with the name "Sessions" in database.

That's it. You don't need to do anything else. It will automatically create a new table in the database and also remove expired sessions automatically. You need at least one session object to be declared in your application, to generate session row in the database. 

Using ASP.NET Universal Providers custom session provider in place of default SQL Server option is an easier and good approach, especially when you are working with Azure.