Hosting Using Internet Information Services

Web service development on IIS has long been the domain of ASP.NET. When ASP.NET 1.0 was released, a web service framework was part of it. Microsoft leveraged the ASP.NET HTTP pipeline to make web services a reality on the Windows platform. Unfortunately, this tight coupling between ASP.NET and web services comes with several limitations in the service orientation world; the dependency on HTTP is the main culprit. Running the ASP.NET HTTP pipeline on a different host is hard and therefore is an uncommon scenario. Even then, ASP.NET web services (a.k.a. ASMX services) stay very web oriented in terms of deployment scenarios and configuration dependencies. Microsoft initially released several version of the Web Services Enhancements (WSE) to cover some of the limitations of ASP.NET web services, and especially to address the limitations in the implementation of the WS-* protocols. However, WSE was very dependent on the ASP.NET web service implementation.

As you learned in previous chapters, WCF services take a totally different approach to make service orientation a reality. The unified programming model of WCF is based on a strictly layered model to break the web-oriented paradigm and disconnect the service model and channel layer from the supported transports. This model allows WCF to support several different hosts of which IIS is the most important.

WCF was built to support Windows XP, Windows Server 2003, Windows Vista, and Windows Server 2007. Since IIS 5.1, which was released with Windows XP, a lot has changed. Still, Microsoft succeeded in supporting WCF on older versions. This was possible because of the features that the Microsoft .NET Framework and the CLR provide, which is what WCF is built on. In the following sections, you will learn the differences in the process models of the different IIS versions and the consequences for your WCF services.

Core IIS 5.1 and 6.0 Features

To be able to explain the differences, we first have to explain the core features of IIS. IIS has long been supporting multiple sites and multiple applications on one machine. To enable this, IIS introduced a common address model that is split into three main areas:

  • Sites []

    [] IIS 5.1, released with Windows XP, supports only one site.

  • Applications

  • Virtual directories

Sites are bound to a particular scheme, network address, and port combination. IIS not only supports HTTP but also, depending on the version, FTP, NNTP, and SMTP. You can run multiple applications under the same site and under the same scheme, network, and port combination. A typical URI for an application is http://localhost/MyApplication. A virtual directory is simply a folder that is mapped to the network space of the site, which could be somewhere else on the file system. This way, you can keep the actual content or code of an application separate from the other applications that are part of the same site.

In IIS 6.0 Microsoft made some significant changes in the IIS process model. The IIS process model was split into application pools that can be shared among sites and applications, where each application runs in its own application domain. An application pool is a separate Windows worker process called W3wp.exe and is started only when it needs to start. In other words, IIS comes with an application activation model that allows IIS to start up an application pool when it receives a request for a particular application that is bound to that application pool. This enables IIS to host several thousands of applications on one server without keeping several thousand processes running. The activation architecture of IIS is an interesting model in the services world, as you will see in the "Windows Activation Services" section of this chapter.

Figure 5-9 shows the core IIS 6.0 architecture on the bottom of the HTTP protocol stack and on top of that at least four different processes:


Lsass.exe

Is responsible for the security features in IIS: the implementation of Windows Authentication and Secure Sockets Layer (SSL).


Inetinfo.exe

Is the process that hosts the non-HTTP services and the IIS Admin Service, including the Metabase.


SvcHost.exe

Is the process that can host operating system services; in the case of IIS, it hosts the web (HTTP) service.


W3wp.exe

Is a worker process. IIS can have multiple W3wp.exe processes, one for each application pool. To support web garden scenarios where one application is split in separate processes, you have multiple instances of the same worker process. This can provide additional scalability and performance benefits.

IIS 6.0 core architecture

NOTE

We are describing the IIS 6.0 architecture here because that was the most widely used version of IIS before the release of WCF. In addition, WCF supports IIS 6.0, and the model closely resembles the implementation that was chosen with IIS 7.0 and Windows Activation Services, as you will learn in the remainder of this chapter. The main difference between IIS 5.1 and IIS 6.0 is the limitation in the amount of sites and application pools. IIS 5.1 supports only one site bound to one application pool.

Hosting WCF Services in IIS

To host a WCF Service in IIS, you need a new physical file with the .svc extension. The file associates a service with its implementation and is the means for IIS to create ServiceHost for you. IIS takes over the interaction between your service and ServiceHost; you no longer have to instantiate and start ServiceHost yourself. The first line of the .svc file contains a directive enclosed in the ASP.NET <% Page %> directive that tells the hosting environment to which service this file points. The service code can then reside inline as shown in Listing 5-3, in a separate assembly registered in the GAC, in an assembly that resides in the application's Bin folder, or in a C# file that resides under the application's App_Code folder. The most common scenario is to define endpoints in a configuration file. In IIS you have to define your endpoints in the Web.config file, as explained in the next section.

Listing 5-3 shows a sample .svc file based on the TradeService service you saw earlier. It has the service code defined inline. Listing 5-4 shows an example .svc file where the code resides in the App_Code folder.

Example. ExchangeServiceInline.svc File with Inline Code
<%@ServiceHost Language="C#"
Service="QuickReturns.StockTrading.ExchangeService.TradeServiceInline" %>

using System;
using System.Collections;
using System.ServiceModel;
using QuickReturns.StockTrading.ExchangeService.Contracts;
using QuickReturns.StockTrading.ExchangeService.DataContracts;

namespace QuickReturns.StockTrading.ExchangeService
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,
                    IncludeExceptionDetailInFaults=true)]
    public class TradeServiceInline : ITradeService
    {
        public Quote GetQuote(string ticker)
        {
             ...
        }

public void PublishQuote(Quote quote)
        {
             ...
        }
    }
}

Example. ExchangeService.svc File with External Code
<%@ ServiceHost language="C#"
Service=" QuickReturns.StockTrading.ExchangeService.TradeService"
CodeBehind="~/App_Code/TradeService.cs" %>

NOTE

The sample code that comes with this book contains the TradeService service hosted inline and comes with its implementation in the App_Code folder to illustrate the concepts in this section. You can find it by opening the Chapter 5 solution file.

Configuring WCF Services in IIS

Hosting in IIS means you will have to set up the WCF configuration in the Web.config file of the application where you want to host your service. The service configuration in the Web.config file is similar to that of self-hosted services. Listing 5-5 shows an example of a Web.config file for the TradeService service.

Example. Web.config Used to Configure a Service Hosted in IIS
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <system.serviceModel>
      <services>
         <service name="QuickReturns.StockTrading.ExchangeService.TradeService"
                  behaviorConfiguration="tradeServiceBehavior">
         <endpoint name="basicHttpBinding"
                   address=""
                   binding="basicHttpBinding"
                   contract="QuickReturns.StockTrading.ExchangeService.
Contracts.ITradeService"/> <endpoint name="mexHttpBinding" contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /> </service>

<service name="QuickReturns.StockTrading.ExchangeService.TradeServiceInline"
               behaviorConfiguration="tradeServiceBehavior">
            <endpoint name="basicHttpBinding"
                      address=""
                      binding="basicHttpBinding"
                      contract="QuickReturns.StockTrading.ExchangeService.
Contracts.ITradeService"/> <endpoint name="mexHttpbinding" contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="tradeServiceBehavior" > <serviceMetadata httpGetEnabled="true" /> </behavior> <behavior name="returnFaults" returnUnknownExceptionsAsFaults="true"/> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>

Please note that the address attribute of the service is empty. The .svc file determines the base address of the service. You can, however, provide an additional string that would set the endpoint's address relative to the .svc file. For example, you can use http://localhost:8080/QuickReturns/Exchange.svc/ExchangeService.

The service name attribute specified in the config file functions as a lookup key for the corresponding ExchangeService.svc. It tells the hosting environment to which service this configuration belongs. The other attributes on the endpoint level are the same as explained previously.

In IIS, web configuration files can be nested in sites, applications, and virtual directories. WCF takes all the configuration files into account and merges services and their endpoints together. This means nested Web.config files are additive to each other, where the last file read in the bottom of the hierarchy takes precedence over files higher in the hierarchy.

Accessing ServiceHost in IIS

The default behavior of hosting your WCF services in IIS is that IIS controls the instantiation of ServiceHost. This limits you from having start-up and shutdown code before a message reaches your service. The advantage of no start-up and shutdown code is, of course, less code that potentially introduces errors. IIS provides you with an easier hosting environment, in terms of lines of code, than a console application. However, sometimes you need a way to circumvent this limitation. To do this and influence IIS in instantiating ServiceHost, you can build your own factory that creates your custom host. This way, you can access any of the events or override any of the methods you like.

To support custom ServiceHost activation, you should implement your own Factory that inherits from ServiceHostFactory, which is a factory class that can instantiate your custom host. That class is provided in order to hook up the events for ServiceHost; you can use this class and put the type as the Factory attribute in the .svc file, as shown in Listing 5-6. By overriding the CreateServiceHost method of the ServiceHostFactory class, you can perform similar tasks as you do in self-hosting scenarios, as you learned in Chapter 3. This enables you, among other things, to abstract the logic to build up the description from the external configuration or create a more suitable base class for your base library, project, department, or company to use.

Listing 5-7 shows the code of TradeServiceCustomHost and TradeServiceCustomHostFactory that creates the host.

Example. .svc File with a CustomServiceHostFactory
<%@ServiceHost Language="C#" Debug="true"
   Service="QuickReturns.StockTrading.ExchangeService.TradeService"
   Factory="QuickReturns.StockTrading.ExchangeService.
TradeServiceCustomHostFactory" %>

Example. TradeServiceCustomHostFactory and TradeServiceCustomHost
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace QuickReturns.StockTrading.ExchangeService
{
   public class TradeServiceCustomHostFactory : ServiceHostFactory
   {
      protected override ServiceHost CreateServiceHost(
         Type serviceType, Uri[] baseAddresses)
      {
         TradeServiceCustomHost customServiceHost =
            new TradeServiceCustomHost(serviceType, baseAddresses);
         return customServiceHost;
      }
   }

   public class TradeServiceCustomHost : ServiceHost
   {
      public TradeServiceCustomHost(Type serviceType, params Uri[] baseAddresses)
         : base(serviceType, baseAddresses)
      {
      }

protected override void ApplyConfiguration()
      {
         base.ApplyConfiguration();
      }
   }
}

Recycling

When you are hosting WCF services on IIS, the WCF services enjoy all the features of ASP.NET applications. You have to be aware of these features because they can cause unexpected behavior in the services world. One of the major features is application recycling, including application domain recycling and process recycling. Through the IIS Management Console, you can configure different rules when you want the recycling to happen. You can set certain thresholds on memory, on time, and on the amount of processed requests, as shown in Figure 5-10. When IIS recycles a worker process, all the application domains within the worker process will be recycled as well. Usually when critical files in an ASP.NET-based web application change, the application domain also recycles. This happens, for example, when changing the Web.config file or assemblies in the Bin folder.

Application pool recycling settings

NOTE

The process recycling described here covers recycling in Windows Server 2003. To enable process recycling in Windows XP and IIS 5.1, you can download the IIS 5.0 process recycling tool from the Microsoft website. The process recycle tool runs as a service on a computer running IIS 5.0 or 5.1.

After modifying an .svc file, the application domain is also recycled. The hosting environment will try to close all the WCF services' open connections gracefully in a timely manner. When services somehow don't close in time, they will be forced to abort. Through the HostingEnvironmentSettings configuration settings, you can influence the behavior of recycling, as you can see in Listing 5-8. The idleTimeout setting determines the amount of idle time in seconds for an application domain to be recycled. The shutdowntimeout setting determines the amount of time in seconds to gracefully shut down an application. After this timeout, it forces applications to shut down.

Example. Web.config with hostingenvironment Section for Recycling Settings
<system.web>
    <hostingEnvironment idleTimeout="20"
                        shutdownTimeout="30"/>
</system.web>

When you are using WCF sessions, these recycling features are critical to understand. This is typically the case in the security and reliable messaging scenarios, as you will read in Chapters 6 and 8 of this book. By default, WCF stores session state in memory. This is a different implementation from ASP.NET session state and doesn't come with a configuration to switch over to persistent session state storage. However, in the security and reliable messaging scenarios you can, and should, benefit from the ASP.NET implementation. Using the ASP.NET compatibility features of WCF provides you with the SQL Server and state server implementations of ASP.NET session state to support enterprise-ready scenarios. In the next section, you will learn how to benefit from the WCF ASP.NET compatibility mode.

ASP.NET Compatibility Model

When hosting your WCF services in a load-balanced or even a web garden environment where subsequent requests in a session can be processed by different hosts or processes in the environment, you need out-of-process persistent storage for your session state. Out-of-the box WCF doesn't support persistent storage for session state. Instead, WCF stores all its session state in memory. When your WCF services are hosted in IIS, you can end up with recycling scenarios, as described in the previous section. Instead of building persistent storage for sessions all over again, WCF relies on the ASP.NET implementation for session state. This approach has one serious limitation: you limit your services to HTTP.

ASP.NET session state is not the only feature that is supported by the ASP.NET compatibility mode. It also supports features such as the HttpContext, globalization, and impersonation, just like you are used to with ASP.NET web services (ASMX). Refer to MSDN Help for the ASP.NET-specific features to enable out-of-process session state.

To see the limitation of the ASP.NET compatibility mode, you have to explicitly mark your services with the AspNetCompatibilityRequirements attribute, as shown in Listing 5-9.

Example. AspNetCompatiblityRequirements Attribute
namespace QuickReturns.StockTrading.ExchangeService
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,
                    ReturnUnknownExceptionsAsFaults=true)]

[AspNetCompatibilityRequirements(
     RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
    public class TradeService : ITradeService
    {
    ...
    }
}

The AspNetCompatibilityRequirementsMode attribute has the following allowed values:


NotAllowed

Indicates your services may never be run in the ASP.NET compatibility mode. You have to set this in scenarios where your service implementation doesn't work in ASP.NET compatibility mode, such as in scenarios where your services are not built for HTTP.


Allowed

Indicates your services may run in the ASP.NET compatibility mode. Pick this value only when you know your service may work in this mode.


Required

Indicates your service must run in the ASP.NET compatibility mode. Pick this value when your service requires persistent session storage.

When you choose the Required option, WCF will verify that all the supported endpoints for the services are HTTP endpoints and will throw an exception during ServiceHost initialization if they aren't. In addition to the AspNetCompatibilityRequirements attribute, you must set aspNetCompatibilityEnabled, as shown in Listing 5-10.

Example. Configuration with ASP.NET Compatibility Enabled
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
      <services>
      ...
      </services>
      <behaviors>
      ...
      </behaviors>
  </system.serviceModel>
</configuration>

NOTE

The sample code that comes with this book contains the TradeService service hosted in the ExchangeServiceInline.svc file that is configured to run in ASP.NET compatibility mode. You can find it by opening the Chapter 5 solution file.

Windows XP and IIS 5.1

IIS 5.0, which came as part of Windows 2000, split the process model of IIS and introduced worker processes. The primary reason for this change was to isolate applications so that IIS could host different applications that were less dependent on each other. IIS 5.0 was released with Windows 2000, and IIS 5.1 was released with Windows XP. WCF doesn't support hosting services on Windows 2000 with IIS 5.0; because of that, we will take a closer look at IIS 5.1 only. IIS 5.1 is supported but has a limitation of only one site, and each application runs in one worker process called aspnet_wp.exe. IIS 5.1 is a great version for developing ASP.NET websites and WCF services. It is not ready for enterprise use because it has connection limits and runs only on a client version of earlier Windows versions or Windows XP. In this chapter, we will talk about IIS 5.1

In Figure 5-11 you can see the process model of IIS 5.1. The architecture is split into two pieces. W3svc.exe on the left side hosts an HTTP listener, launches worker processes, and manages the configuration. The worker processes on the other side enable IIS 5.1 to host managed .NET applications, where ASPNET_ISAPI.dll is responsible for creating managed .NET application domains. Please note that on Windows XP the W3svc.exe Windows service is hosted in the SvcHost.exe process, together with the SMTP and FTP services.

IIS 5.1 process model architecture

NOTE

You aren't required to have IIS to run ASP.NET and WCF services. For example, you can use the ASP.NET development web server that is provided with Visual Studio 2005. When Windows XP was released, Visual Studio didn't have this feature. You were required to work with IIS 5.1 to be able to develop web applications on Windows XP.

Windows Server 2003 and IIS 6.0

As of Windows Server 2003, Microsoft introduced the kernel mode HTTP stack called HTTP.SYS. HTTP.SYS is plugged into the IIS 6.0 architecture through W3svc.exe. W3svc.exe is a user mode component that bridges the kernel mode implementation of HTTP.SYS and connects this to the process and configuration management system that was already there in IIS 5.1. And as of IIS 6.0, the concept of application pools was more generalized. Although in IIS 5.1 only managed (ASP.NET) applications could be hosted in separate application pools, in IIS 6.0 all types of applications can be hosted in separate application pools. ASPNET_ISAPI.dll is still responsible for starting application domains in the managed ASP.NET world. Figure 5-12 illustrates the process model in IIS 6.0.

IIS 6.0 process model architecture

To host your services in IIS 6.0, please refer to Chapter 4.

Hosting in IIS 7.0

IIS 7.0 has established another big evolution in the web server world. As you can see in Figure 5-13, two big changes were made. First, now protocol-specific listener adapters support all four WCF transports, instead of only HTTP in IIS 6.0. In addition, a new operating system service is available called Windows Activation Services (WAS). Both W3svc.exe and WAS are running inside an operating system host called SvcHost.exe. To be able to use the power of the IIS 6.0 process model in conjunction with WCF, these changes were necessary. Why? you may ask. Well, WCF services also work in IIS 5.1 and IIS 6.0, so what benefits could you get by generalizing the process model and activation features in IIS? Simple—by generalizing the activation concept to make it protocol agnostic, instead of being bound to HTTP, you expand the activation features of the platform to basically all transports.

IIS 7.0 process model architecture

With the release of Windows Vista and Windows Server 2007, Microsoft moved the process management and configuration features of IIS and made this generally available inside the operating system. This enables any application built on top of that model to use the power of runtime activation and spawning worker processes based on messages coming in.

The protocol-specific listener adapters for HTTP, TCP/IP, Named Pipes, and MSMQ live inside their own process and are bridging the specific transports over to WAS. Listener adapters ask WAS to activate worker processes and then hand over the actual communication to the specific protocol handler inside these worker processes. So, WAS now has all the features that used to be part of W3svc.exe. By splitting this responsibility into separate processes, the three other transports also benefit from the process model and activation features that used to be built into IIS 6.0, but only for HTTP. To summarize, with IIS 7.0 you can host any WCF service across any transport that is provided out of the box inside IIS. In the next section, you will learn how WAS activation works and what you need to be aware of when you want to host your WCF services inside IIS 7.0 and WAS on Windows Vista or Windows Server 2007.

To host the TradeService that you have been using throughout this book inside IIS 7.0, all you have to do is configure IIS and place the .svc file created for IIS 6.0 in the site you will create. The following steps will enable you to configure IIS 7.0, WAS, and the .NET Framework 3.0 on Windows Server 2007 and get your TradeService running inside IIS 7.0:

  1. Start the Server Manager (found in Administrative Tools).

  2. Add the Web Server (IIS) role to the server.

  3. Note that the web server installation automatically adds WAS.

  4. On the Detailed Settings screen for IIS, select ASP.NET, and under Security select Basic and Windows Authentication. Keep the rest in its default settings.

  5. This will install IIS and WAS.

  6. By default, Windows Server 2007 comes without the .NET Framework 3.0 installed. To install .NET Framework 3.0, open the Add Features Wizard (Control Panel Programs Windows Features).

  7. Click Add Features, and select .NET Framework 3.0 (if you want to experiment with the WCF MSMQ transport). Also select MSMQ.

Now you are all set to run your WCF services on IIS 7.0. The next step is to create an application in IIS in which to run your service. For this you need the Internet Information Services (IIS) Manager. You can find the IIS management tool in Administrative Tools in the Start menu. Then navigate to your server, then to your websites, and finally to the default website. Right-click the default website, and select Create Application, as illustrated in Figure 5-14.

Creating a new application in the Internet Information Services (IIS) Manager

Now you need a folder on your local machine where you want to host your application's .svc files. As illustrated in Figure 5-15, you can give the application a name where the service can be reached (http://localhost/<chosenname>) and the folder where the files reside, and you can select the application pool.

Setting the properties for a new application in the Internet Information Services (IIS) Manager

If you did everything correctly, your service is reachable through IIS 7.0. You can test this by navigating to your newly created application, for example: http://localhost:8080/QuickReturns/Exchange.svc/ExchangeService.

Windows Activation Services

WAS enables you to host any WCF service, supporting any transport inside the IIS model. WAS takes over creating worker processes and providing the configuration from the original W3svc.exe Windows service that you know from IIS 6.0 (and runs inside the Inetinfo.exe process). WAS and IIS now share the configuration store that defines sites, applications, application pools, and virtual directories. In this section, we'll walk you through the process of activation with WAS, as shown in Figure 5-16.

By default when no requests are being made to a newly booted server, Windows runs five services (if all the protocols are enabled). These are the following Windows services:

  • WAS

  • World Wide Web Publishing Service (hosting the listener adapter)

  • NET.TCP listener adapter

  • NET.PIPE listener adapter

  • NET.MSMQ listener adapter

When the listener adapters start, they register themselves with WAS and receive the WAS/IIS configuration for their specific protocols. In this way, the listener adapters are aware of the sites and applications they should support. Each listener adapter then starts listening on the appropriate ports provided with the configuration so it can dispatch the requests coming in to the appropriate application.

Activation of worker processes with WAS for an HTTP request

As soon as the first request comes in, the listener adapter will call WAS to activate the worker process, including a managed .NET application domain for the specific application for which the request is destined.

The request is then handed over to the so-called application domain protocol handler inside the worker process to handle the request and return the response to the client. It doesn't matter whether the request is a WCF service request, an ASP.NET request, or any other request for IIS 7.0. The activation process is created to enable worker processes to start when requests come in.

To start the WCF ServiceHost inside the application domain, the application domain protocol handler must call the static method called EnsureServiceAvailable. That method is protocol agnostic and activates the entire service including all endpoints and transports (not only the transport for the protocol handler that calls the method).

NOTE

Inside the listener adapters and protocol handlers, some true magic is happening for HTTP and TCP in particular. Sockets are opened inside the listener adapters hosted in a separate process. Then when the first request comes in, the socket is actually handed over from the listener adapter to the application domain protocol handler to be able to handle the first request and any subsequent requests!

Hosting Options

In the previous section of this chapter, you learned the different options you have to host your services. In addition, you learned which business requirements (or nonfunctional requirements) can be covered by which hosting scenario. In general, you can apply a "Why not IIS?" approach. What do we mean by that? IIS provides the best match in terms of features, in particular in scenarios where your services are exposing key business functionality on which multiple systems rely. When you choose IIS and then have to choose between IIS 6.0 and IIS 7.0, you should obviously choose the latter because of the new activation features. In scenarios where you need interprocess communication, both WinForms and console applications are viable options. Windows services are essentially the only alternative to IIS and will typically be used when you are building a server product or when you need advanced control over the activation and lifetime of your services.

In the next section, we will go through the options you have to consume your services and what the hosting option means for the consumer side.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset