Advanced Web and Worker Roles
Exercise 1: Registering Sites, Applications, and Virtual Directories

Collapse All Expand All Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C#

Visual Basic Usage
C#

When hosted in IIS Hosted Web Core (HWC), Windows Azure Web roles can support a single application bound to no more than a single HTTP and a single HTTPS endpoint. This model is enabled with minimal configuration and was the only one originally supported in Windows Azure when it was first introduced. To use HWC, you only need to specify the HTTP and HTTPS endpoints bound to the Web application in the service model, as shown in the figure below.

Figure 1
Simplified service model for Hosted Web Core (HWC) hosting

While this approach is still valid and you can use it in many scenarios where a single application per role is sufficient or does not require multiple endpoints, more advanced capabilities are now available that provide full access to all IIS features. In this advanced model, applications are hosted in IIS instead, both in Windows Azure and in the compute emulator, allowing each role to support multiple sites, virtual applications and virtual directories, as well as providing support for binding each site to multiple endpoints.

To enable the Full IIS capabilities, the service model defines a Sites element that can contain one or more Site definitions, where each site is bound to one or more endpoints, as shown in the following figure.

Figure 2
Advanced service model for Full IIS hosting

In this exercise, you will learn how to define different sites, applications, and virtual directories within a Web role using a single Web role application, which you will map to multiple sites. To show site customization, you will modify the master page of the application to show the site name on each page. During the exercise, you will create a Virtual Application for a hypothetical CRM application and enable it for selected sites. Additionally, you will use Virtual Directories to share common content between applications.

Task 1 – Defining Multiple Sites in a Web Role Using the Service Model

The service model in Windows Azure is determined by the service definition file, which defines the roles that comprise a service, optional local storage resources, configuration settings, certificates for SSL endpoints, and, as you will see in the following exercise, start-up tasks.

In this task, you edit the service model to define three separate sites that map to the same Web application, namely, Contoso, Fabrikam, and Litware. These sites are all bound to a single endpoint and use host headers to isolate them.

Note:
This task requires the hosts file to be updated. If you did not execute the setup instruction for this lab, this exercise will not work. Proceed with the setup instructions before starting with this task.

1. Start Microsoft Visual Studio 2010 as an administrator.
2. Open the Begin solution located in Ex1-FullIIS in the Source folder of the lab.
3. In the Windows Azure project, open the service model file, ServiceDefinition.csdef. Notice that it defines a single Web role named SampleWebApp, which in turn defines a site named Web.
4. In the Sites element of the SampleWebApp Web role, locate the nested Site element named Web and change its name attribute to Fabrikam. Next, add a physicalDirectory attribute to this element that points to "..\SampleWebApp".

   Note:
   This step changes the name of the site from its Web default value to Fabrikam. Note that for sites other than the default Web site, you need to specify a physical directory for the site’s content.

5. Now, locate the single Binding element for the Fabrikam site and add a hostHeader attribute with a value of "www.fabrikam.com". The updated site definition should appear as shown in the following figure.

   Figure 3
   Definition for the Fabrikam site

   Note:
   The updated endpoint binding ensures that the site only responds to traffic that specifies the appropriate host header, namely requests for www.fabrikam.com.

6. Next, define a new site for Contoso by inserting the following (highlighted) definition inside the Sites element.

   (Code Snippet – AdvancedWebAndWorkerRoles-Ex1-01-ContosoSite-XML)

   XML | Copy Code
   --- | ---
       <WebRole name="SampleWebApp">
         <Sites>
           <Site name="Fabrikam" physicalDirectory="..\SampleWebApp">
             <Bindings>
               <Binding name="HttpIn" endpointName="HttpIn" hostHeader="www.fabrikam.com" />
             </Bindings>
           </Site>
           <Site name="Contoso" physicalDirectory="..\SampleWebApp">
             <Bindings>
               <Binding name="HttpIn"
                        endpointName="HttpIn"
                        hostHeader="www.contoso.com" />
             </Bindings>
           </Site>
         </Sites>
         ...
       </WebRole>

7. Similarly, create a site for Litware, as shown (highlighted) below.

   (Code Snippet – AdvancedWebAndWorkerRoles-Ex1-02-LitwareSite-XML)

   XML | Copy Code
   --- | ---
       <WebRole name="SampleWebApp">
         <Sites>
           <Site name="Fabrikam" physicalDirectory="..\SampleWebApp">
             <Bindings>
               <Binding name="HttpIn"
                        endpointName="HttpIn"
                        hostHeader="www.fabrikam.com" />
             </Bindings>
           </Site>
           <Site name="Contoso" physicalDirectory="..\SampleWebApp">
             <Bindings>
               <Binding name="HttpIn"
                        endpointName="HttpIn"
                        hostHeader="www.contoso.com" />
             </Bindings>
           </Site>
           <Site name="Litware" physicalDirectory="..\SampleWebApp">
             <Bindings>
               <Binding name="HttpIn"
                        endpointName="HttpIn"
                        hostHeader="www.litware.com" />
             </Bindings>
           </Site>
         </Sites>
         ...
       </WebRole>

   Note:
   All three sites are mapped to the same physical directory ("..\SampleWebApp") and bound to the same HTTP endpoint (HttpIn). The endpoint binding, however, specifies a different host header value for each site.

8. Press F5 to build and run the Windows Azure project. Wait for the application to launch in the compute emulator and for the browser to open pointing at the default site address. Notice that it shows an error page with a status “HTTP 400 Bad Request”.

   Note:
   By default, the Windows Azure Tools for Visual Studio opens the default Web site in your browser. In this case, however, you have removed the default mapping and there is no longer any site accessible without the use of a host header, which explains the error response.

9. Start Internet Information Services (IIS) Manager.
10. Browse to the Sites node and notice that three new sites were created for Fabrikam, Contoso and Litware. The name of the site is derived from the Windows Azure deployment ID, the Web role name, the instance ID, and the name of the site in the service model file.

    Figure 4
    Internet Information Services (IIS) Manager showing the sites created by the Web role

11. In the (IIS) Manager, click Contoso node and take note of the port where it is hosted. You will find the port number in the right pane, inside Manage Web Site. Repeat this action with Fabrikam and Litware nodes. You will use these ports later in this exercise.

    Figure 4
    Application Port

12. Now, select the Application Pools node and review the pools created to support the applications hosted by the Web role.

    Figure 5
    Application pools defined for the Web role sites

13. In the browser window, change the address to that of the Contoso site. Make sure to use the same port number you obtained in the step 11. For example, if the browser is currently showing http://127.0.0.1:81, set the address to http://www.contoso.com:82.

    Note:
    The setup procedure updated the hosts file, adding three new entries for www.contoso.com, www.fabrikam.com, and www.litware.com, all pointing to the loopback address (127.255.0.0).

14. Notice that the title shown in the home page is “My ASP.NET Application”.
15. In Visual Studio, open the Site.Master file in the SampleWebApp project. Inside the body of the page, locate the h1 element nested inside a div element with its class set to title. Replace its content, which should be “My ASP.NET Application”, with the following (highlighted) expression.

    (Code Snippet – AdvancedWebAndWorkerRoles-Ex1-03-SampleWebAppTitle-HTML)

    HTML | Copy Code
    --- | ---
        ...
        <body>
          <form runat="server">
          <div class="page">
            <div class="header">
              <div class="title">
                <h1>
                  <%= System.Text.RegularExpressions.Regex.Match(System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName(), "[^_]+$").Value%>
                </h1>
              </div>
            <div class="loginDisplay">
            ...

            </form>
        </body>
        ...

    Note:
    The added code retrieves the Web site name using the ApplicationHost class in the System.Web.Hosting.Environment namespace and then uses a regular expression to extract a friendly name for the site.

16. Save the updated file.
17. In the browser window, refresh the page and notice how the title of the page now shows “Contoso” instead of “My ASP.NET Application”.

    Note:
    Editing the site content while the application is running is a useful technique to use during debugging, allowing you to apply changes without restarting the deployment. Be aware that this requires the role to be hosted in IIS; otherwise, when using the simple service model that uses Hosted Web Core (HWC), changes only become effective after redeploying the service.

18. Open a new browser window and navigate to www.litware.com. Notice that the Web site title in the new window is Litware. Similarly, open a third browser window and navigate to www.fabrikam.com.

    Note:
    Remember to specify the correct port number for each address if the deployment is not using the standard HTTP port (80).

    Figure 6
    Multiple sites hosted in the Web role

    Note:
    In this particular case, all three sites are mapped to the same physical directory but use host headers to identify which site responds to a request. A Web role application can extract the site name from the request, as was shown earlier for the title, and then customize the output to render the pages differently depending on the requested site. You can, of course, map each site to a different physical directory and use different content for each one.

19. Close all browser windows.

Task 2 – Creating Virtual Applications and Virtual Directories

In this task, you create a new Virtual Application for an application that you only enable for selected sites.

1. In Visual Studio, add the sample CRM application project located in the Assets folder of the lab to the solution.
2. Now, in the Windows Azure project, open the service model file ServiceDefinition.csdef.
3. Locate to the Site element for the Contoso site and insert the VirtualApplication definition, as shown (highlighted) below.

   (Code Snippet – AdvancedWebAndWorkerRoles-Ex1-04-ContosoVirtualApplicationDefinition-XML)

   XML | Copy Code
   --- | ---
       <WebRole name="SampleWebApp">
         <Sites>
           <Site name="Fabrikam" physicalDirectory="..\SampleWebApp">
             ...
           </Site>
           <Site name="Contoso" physicalDirectory="..\SampleWebApp">
             <VirtualApplication name="CRM"
                                 physicalDirectory="..\..\..\..\Assets\CRM">
               <VirtualDirectory name="Scripts"
                                 physicalDirectory="..\SampleWebApp\Scripts" />
               <VirtualDirectory name="Styles"
                                 physicalDirectory="..\SampleWebApp\Styles" />
             </VirtualApplication>
               ...
           </Site>
           <Site name="Litware" physicalDirectory="..\SampleWebApp">
             ...
           </Site>
         </Sites>
         ...
       </WebRole>

   Note:
   The virtual application definition shown above creates a new Web application in the Contoso site and maps it to the CRM path, thus, making it reachable at http://www.contoso.com/CRM. Because the CRM site shares content with the main site, in particular, its Scripts and Styles folders, these are created as virtual directories under the CRM site and mapped to the corresponding physical directories present in the main site.

4. Similarly, enable the CRM application for the Litware site by inserting the following (highlighted) virtual application definition.

   (Code Snippet – AdvancedWebAndWorkerRoles-Ex1-05-LitwareVirtualApplicationDefinition-XML)

   XML | Copy Code
   --- | ---
       <WebRole name="SampleWebApp">
         <Sites>
           <Site name="Fabrikam" physicalDirectory="..\SampleWebApp">
             ...
           </Site>
           <Site name="Contoso" physicalDirectory="..\SampleWebApp">
             ...
           </Site>
           <Site name="Litware" physicalDirectory="..\SampleWebApp">
             <VirtualApplication name="CRM"
                                 physicalDirectory="..\..\..\..\Assets\CRM">
               <VirtualDirectory name="Scripts"
                                 physicalDirectory="..\SampleWebApp\Scripts" />
               <VirtualDirectory name="Styles"
                                 physicalDirectory="..\SampleWebApp\Styles" />
             </VirtualApplication>
             ...
           </Site>
         </Sites>
         ...
       </WebRole>

5. Press F5 to build and launch the application in the compute emulator.
6. In the browser window, navigate to http://www.contoso.com, making sure that you specify the port number for the running deployment, if this is different from the standard HTTP port (80).
7. Now, navigate to http://www.contoso.com/CRM to view the CRM application running in the Contoso site.

   Figure 7
   CRM virtual application mapped to the Contoso site

8. Repeat the previous step, only this time visit the same CRM application running in the Litware site.
9. Close the browser window.