Exercise - Store session state information in an ASP.NET web app

Completed

Many session-state providers are available for ASP.NET web applications. For a web app running under Azure App Service, using the Azure Cache for Redis provider can offer the scalability and performance required to support large numbers of concurrent sessions. That's especially true when requests to the same session are directed to different instances of the web app.

In this exercise, you'll create an instance of the Azure Cache for Redis service. You'll configure the session provider for the example web app to use this cache. You'll then verify that the application is using the cache to store session state information.

Create an instance of Azure Cache for Redis

  1. In the Azure Cloud Shell window on the right, run the following command to define a PowerShell variable that contains the name of the Azure Cache for Redis instance to be created:

    $rediscachename = (-join($useralias, "-workshop-cache"))
    
  2. Create an Azure Cache for Redis instance. This command can take up to 15 minutes to complete:

    az redis create `
        --location $location `
        --name $rediscachename `
        --resource-group $resourcegroupname `
        --sku Basic `
        --vm-size c0
    
  3. Run the following command to check the provisioning state of the cache. Repeat this command every 30 seconds until it displays the message Succeeded:

    (Get-AzRedisCache `
        -ResourceGroupName $resourcegroupname `
        -Name $rediscachename).ProvisioningState
    
  4. Retrieve the primary access key for the cache and record it to use later:

    $rediskey = (Get-AzRedisCacheKey `
        -Name $rediscachename `
        -ResourceGroup $resourcegroupname).PrimaryKey
    

Configure the session provider in the web app

  1. Return to Visual Studio, editing the eShopLegacyWebForms solution.

  2. In the Solution Explorer window, right-click the eShopLegacyWebForms project, then select Manage NuGet Packages.

    Screenshot of the shortcut menu for the eShopLegacyWebForms project in the Solution Explorer window with Manage NuGet Packages selected.

  3. In the NuGet Package Manager window, select Browse. In the Search box, enter Microsoft.Web.RedisSessionStateProvider. Select the Microsoft.Web.RedisSessionStateProvider package and select Install.

    Screenshot of the NuGet Package Manager window installing the Microsoft.Web.RedisSessionStateProvider package.

  4. If the Preview Changes window appears, select OK.

    Screenshot of the Preview Changes window with OK selected.

  5. In the License Acceptance window, select I Accept.

    Screenshot of the License Acceptance window with I Accept selected.

  6. In the Solution Explorer window, select the web.config file.

  7. In the web.config file, find the sessionState section. It looks like this:

    <sessionState mode="Custom" customProvider="MySessionStateStore">
      <providers>
        <!-- For more details check https://github.com/Azure/aspnet-redis-providers/wiki -->
        <!-- Either use 'connectionString' OR 'settingsClassName' and 'settingsMethodName' OR use 'host','port','accessKey','ssl','connectionTimeoutInMilliseconds' and 'operationTimeoutInMilliseconds'. -->
        <!-- 'throwOnError','retryTimeoutInMilliseconds','databaseId' and 'applicationName' can be used with both options. -->
        <!--
          <add name="MySessionStateStore" 
            host = "127.0.0.1" [String]
            port = "" [number]
            accessKey = "" [String]
            ssl = "false" [true|false]
            throwOnError = "true" [true|false]
            retryTimeoutInMilliseconds = "5000" [number]
            databaseId = "0" [number]
            applicationName = "" [String]
            connectionTimeoutInMilliseconds = "5000" [number]
            operationTimeoutInMilliseconds = "1000" [number]
            connectionString = "<Valid StackExchange.Redis connection string>" [String]
            settingsClassName = "<Assembly qualified class name that contains settings method specified below. Which basically return 'connectionString' value>" [String]
            settingsMethodName = "<Settings method should be defined in settingsClass. It should be public, static, does not take any parameters and should have a return type of 'String', which is basically 'connectionString' value.>" [String]
            loggingClassName = "<Assembly qualified class name that contains logging method specified below>" [String]
            loggingMethodName = "<Logging method should be defined in loggingClass. It should be public, static, does not take any parameters and should have a return type of System.IO.TextWriter.>" [String]
            redisSerializerType = "<Assembly qualified class name that implements Microsoft.Web.Redis.ISerializer>" [String]
          />
        --> 
        <add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider" host="" accessKey="" ssl="true" />
      </providers>
    </sessionState>
    
  8. Remove the commented-out content, and amend the entry for MySessionStateStore as shown in the following code. Replace <youralias> with the value of the $useralias PowerShell variable. Replace <primarykey> with the value of the $rediskey PowerShell variable.

    <sessionState mode="Custom" customProvider="MySessionStateStore">
      <providers>
        <add name="MySessionStateStore" 
             type="Microsoft.Web.Redis.RedisSessionStateProvider" 
             host="<youralias>-workshop-cache.redis.cache.windows.net" 
             accessKey="<primarykey>"
             ssl="true" />
      </providers>
    </sessionState>
    
  9. Find the <sessionState mode="InProc" /> element near the start of the <system.web> section and comment it out:

    ...
    <system.web>
      <compilation debug="true" targetFramework="4.7.2" />
      <httpRuntime targetFramework="4.6.1" requestValidationMode="2.0" />
      <!--sessionState mode="InProc" /-->
      ...
    </system.web>
    

Deploy the web app to Azure

  1. In the Solution Explorer window, expand the Models folder, expand the Infrastructure folder, and then select the dbo.catalog_brand_hilo.Sequence.sql file.

    Screenshot of the Solution Explorer window with the dbo.catalog_brand_hilo.Sequence.sql file selected.

  2. In the SQL file, comment out the USE statement at the start of the file:

    -- USE [Microsoft.eShopOnContainers.Services.CatalogDb]
    /****** Object:  Sequence [dbo].[catalog_brand_hilo]    Script Date: 16/08/2017 11:21:49 ******/
    CREATE SEQUENCE [dbo].[catalog_brand_hilo] 
      AS [bigint]
      START WITH 1
      INCREMENT BY 10
      MINVALUE -9223372036854775808
      MAXVALUE 9223372036854775807
    CACHE 
    
  3. Repeat step 2 for the dbo.catalog_hilo.Sequence.sql file and the dbo.catalog_type_hilo.Sequence.sql file. Save all files.

    Note

    The scripts in these files run when the database is seeded with data. This seeding happens automatically the first time the application is run against a new database. The statements that you've commented out are required only when you're running the application locally. When the application runs using the Azure SQL Server database, the database to be used is specified as part of the connection string.

  4. If you aren't currently signed in to your Azure account in Visual Studio, in the upper right of the toolbar, select Sign in. Follow the instructions and sign in.

    Screenshot of the Visual Studio toolbar with Sign in selected.

  5. In the Solution Explorer window, right-click the eShopLegacyWebForms project, then select Publish.

    Screenshot of the Solution Explorer window with the Publish command on the shortcut menu for the eShopLegacyWebForms project selected.

  6. If you haven't previously deployed the web app and configured the connection to the Azure SQL Database server, complete the following substeps. Otherwise, skip to step 7.

    1. Switch back to the Azure PowerShell window. Run the following command to allow your computer to access the Azure SQL Database server that you created in the setup unit. Replace YourIPAddress with the public IP address of your computer.

      New-AzSqlServerFirewallRule -ResourceGroupName $resourcegroupname -ServerName $servername -FirewallRuleName "AllowDesktop" -StartIpAddress YourIPAddress -EndIpAddress YourIPAddress
      

      Note

      Make sure you specify the IP address of your computer, not the IP address of the host running Cloud Shell.

    2. Return to the Pick a publish target window in Visual Studio and select Azure App Service > Select Existing > Create Profile.

      Screenshot of the Pick a publish target window, preparing to create a new profile for publishing the web app to Azure App Service.

    3. In the App Service window, select your Azure subscription. Set View to Resource type. Expand Web App, select the Azure web app that you created during the setup unit, and then select OK.

      Screenshot of the App Service window with the Azure web app created earlier selected.

    4. On the Publish page, select Edit.

      Screenshot of the Publish page with Edit selected.

    5. On the Connection page of the Publish dialog box, select Next.

      Screenshot of the Connection page of the Publish dialog box with Next selected.

    6. On the Settings page, by the Remote connection string text box, select the ellipsis button (...).

      Screenshot of the Settings page of the Publis dialog box with the ellipsis button for the remote connection string selected.

    7. In the Destination Connection String dialog box, specify the values in the following table, and select OK.

      Field Value
      Data source Microsoft SQL Server (SqlClient)
      Server name Specify the value in the $servername PowerShell variable. Append the text .database.windows.net to the end of the server name.
      Authentication SQL Server Authentication
      User name Specify the value in the $serveradminname PowerShell variable.
      Password Specify the value in the $serveradminpassword PowerShell variable.
      Save my password Selected.
      Select or enter a database name eShop

      Screenshot of the Destination Connection String dialog box with the settings required to connect to the eShop database running in Azure SQL Database.

    8. Back on the Settings page, select Use this connection string at runtime (update destination web.config) if it isn't already selected, then select Save.

      Screenshot of the Settings page of the Publish dialog box with Save selected.

  7. On the Publish page, select Publish.

    Screenshot of the Publish page with Publish selected.

  8. Wait while the web app is built and deployed to App Service. When deployment is complete, the web app will start and Visual Studio will open a web browser. Browse through the website to verify that the web app operates in the same way as it did before when running locally. Leave the page for the web app open in the browser.

View cache activity

  1. Sign in to the Azure portal.

  2. Select the Show portal menu button, then select All resources.

    Screenshot of the Show portal menu button in the Azure portal with the All resources option selected.

  3. On the All resources page, select the Azure Cache for Redis instance that you created earlier. It will have the name <useralias>-workshop-cache.

  4. On the Overview pane for the cache, select Console.

    Screenshot of the Overview pane for the cache with Console selected.

  5. In the Redis Console window, at the > prompt, type monitor, then select the Enter key.

    Screenshot of the Console window with the Redis monitor active.

  6. Return to the browser window for the web app and browse through the details of products.

    Note

    The Redis monitor command affects the performance of all operations that use the cache, so you might notice that the web app is slower to respond than normal. You shouldn't use the monitor command in a production system.

  7. Return to the Redis Console window for the cache. You should have messages displaying the cache activity that took place while you browsed through products. The keys that have _Data and _Internal suffixes identify session state information.

    Screenshot of the Console window displaying the activity generated while browsing through the web app.

  8. Select the Enter key to stop monitoring activity.