Home > Articles > Programming > ASP .NET

This chapter is from the book

This chapter is from the book

Using HTTP Handlers and Modules

In the following sections, you learn how to create custom HTTP handlers and modules. Both HTTP handlers and modules enable you to gain low-level access to HTTP requests and responses.

Later, you learn how to implement a simple statistics application for your Web site by using a custom HTTP handler and module.

Working with HTTP Handlers

An HTTP handler enables you to handle all requests made for a file with a certain extension, path, or request type. You can use HTTP handlers to handle requests for ASP.NET pages or any other file type, such as image or text files.

Typical uses for handlers include implementations of custom authentication schemes and custom filters. For example, you can create a handler that authenticates requests for image files. Or you can create a handler that automatically transfers requests for one file to another file.

Classic ASP

HTTP handlers perform many of the same functions in the ASP.NET framework as ISAPI extensions performed in traditional Active Server Pages programming.

All requests made to an ASP.NET Web site are serviced by an HTTP handler. For example, by default, all requests made for files with the extension .aspx are handled by the PageHandlerFactory class. This class produces instances of the PageHandler class to service each request for an ASP.NET page.

To create your own HTTP handler, complete the following steps:

  1. Create a class that implements the IHttpHandler interface.

  2. Add a reference to your HTTP handler in the Web.Config file.

Now, create a simple HTTP handler that retrieves product information from a database table. The handler will take a URL like this:

http://yourSite.com/products/product1.aspx

It will retrieve information for that product from the Products database table.

The first step is to implement the IHttpHandler interface, which requires you to implement one property and one method: IsReusable and ProcessRequest(). The IsReusable property indicates whether the current handler can be reused for another request. The ProcessRequest() method contains the actual code to be executed in response to the request.

The Visual Basic class in Listing 15.15 implements the products handler.

Listing 15.15 ProductsHandler/ProductsHandler.vb

Imports System.Data
Imports System.Data.SqlClient
Imports System.Web

Public Class ProductsHandler
Implements IHttpHandler
 Public Sub ProcessRequest( objContext As HttpContext ) _
 Implements IHttpHandler.ProcessRequest
  Dim intProductID As Integer
  Dim conNorthwind As SqlConnection
  Dim strSelect As String
  Dim cmdSelect As SqlCommand
  Dim dtrProducts As SqlDataReader

  intProductID = GetProductID( objContext.Request.Path ) 
  conNorthwind = New SqlConnection( _
   "Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
  strSelect = "Select ProductName, UnitPrice From Products" & _
   " Where ProductID=@ProductID"
  cmdSelect = New SqlCommand( strSelect, conNorthwind )
  cmdSelect.Parameters.Add( "@ProductID", intProductID )
  conNorthwind.Open()
  dtrProducts = cmdSelect.ExecuteReader( CommandBehavior.SingleRow )
  If dtrProducts.Read Then
   objContext.Response.Write( "<h2>Product Name:</h2>" )
   objContext.Response.Write( dtrProducts( "ProductName" ) )
   objContext.Response.Write( "<h2>Product Price:</h2>" )
   objContext.Response.Write( String.Format( _
    "{0:c}", _
    dtrProducts( "UnitPrice" ) ) )
  End If
  conNorthwind.Close()
 End Sub

 ReadOnly Property IsReusable() As Boolean _
 Implements IHttpHandler.IsReusable
  Get
   Return True
  End Get
 End Property

 Function GetProductID( strPath As String ) As Integer
  Dim intCounter As Integer
  Dim strNumbers As String

  For intCounter = 0 To strPath.Length - 1
   If Char.IsDigit( strPath.Chars( intCounter ) ) Then
    strNumbers &= strPath.Chars( intCounter )
   End If
  Next
  If Not strNumbers = Nothing Then
   Return cINT( strNumbers )
  Else
   Return -1
  End If
 End Function
End Class

The class in Listing 15.15 implements both the ProcessRequest() method and IsReusable property. The ProcessRequest() method uses the GetProductID() function to strip anything but numbers from the page requests. The resulting number is used to retrieve a product with a certain product ID from the Northwind database table. If the product is found, the name and price of the product are displayed (see Figure 15.5).

Figure 15.5 Output of the ProductsHandler.

The IsReusable property simply returns the value True. This is all you need to implement for a simple HTTP handler.

Before you can use the handler, you need to compile it. You can compile the class in Listing 15.15 by executing the following statement from the command line:

vbc /t:library /r:System.dll,System.Data.dll,System.Web.dll ProductsHandler.vb

Next, you need to copy the compiled ProductsHandler class (ProductsHandler.dll) to your application /bin directory.

The last step is to create the proper Web.Config file to associate the handler with a set of pages. The Web.Config file in Listing 15.16 associates the ProductsHandler class with all files requested in the current directory and all its subdirectories.

Listing 15.16 Web.Config

<configuration>
 <system.web>
  <httpHandlers>
   <add verb="*" path="*"
   type="ProductsHandler,ProductsHandler" />
  </httpHandlers>
 </system.web>
</configuration>

The Web.Config file in Listing 15.16 associates the ProductsHandler class with all files. You can limit the files associated with the handler by changing the value of the path attribute. For example, if you want to associate the handler with only those files that have a name starting with product, you would specify the path like this:

<add verb="*" path="product*.*"
type="ProductsHandler,ProductsHandler" />

You can also add multiple entries for a single handler in the Web.Config file.

You should be cautious about one thing: Only certain file extensions are handled by the ASP.NET framework. For example, by default, files with the extension .asp and .html are not handled by the ASP.NET framework. This means that you cannot, by default, create a handler for files with these extensions.

You can associate any file with the ASP.NET framework by modifying the mapping for an extension with the Internet Services Manager. To do so, follow these steps:

  1. Launch the Internet Services Manager.

  2. Right-click the name of your application (virtual directory) and choose Properties.

  3. Choose the Virtual Directory tab and click the Configuration button.

  4. Choose the App Mappings tab and make any desired changes.

You can associate any file extension with the ASP.NET framework by mapping the file extension to the aspnet_isapi.dll file. For example, if you want to write a custom handler for HTML files, you need to map the .html extension to the aspnet_isapi.dll file.

Working with HTTP Modules

An HTTP module is similar to a handler in that it enables you to gain low-level access to the HTTP requests and responses processed by the ASP.NET framework. However, an HTTP module, unlike a handler, enables you to participate in the processing of every request.

The ASP.NET framework includes several standard modules for managing state and implementing authentication schemes. For example, the output cache, session state, forms authentication, and Windows authentication are all implemented as modules.

You can replace any of the standard modules with your own module. For example, if you don't like the way that the ASP.NET framework implements session state, you can replace the standard session state module with one of your own. Or you might decide to extend the ASP.NET framework by creating a completely new module. For example, you might want to implement a custom caching mechanism or create your own custom authentication system.

Creating your own module requires completing the following two steps:

  1. Create a class that implements the IHttpModule interface.

  2. Add a reference to your module to a Web.Config file.

For this next example, create a simple module that implements a custom authentication scheme. The module will require that a parameter named username be passed as part of the parameters collection to a page. If the username parameter is not present, you are automatically redirected to a login page.

The first step is to implement the IHttpModule interface. This interface has two required methods: Init and Dispose. Within the Init subroutine, you can initialize any variables that you need in your module and initialize event handlers with the hosting application. The Dispose event cleans up any of your module's instance variables.

The module in Listing 15.17 implements both of these required methods. (You can find this module in the ModuleAuth subdirectory on the CD-ROM that accompanies this book.)

Listing 15.17 ModuleAuth/AuthModule.vb

Imports System
Imports System.Web
Imports Microsoft.VisualBasic

Namespace myModules

Public Class AuthModule
Implements IHttpModule

Public Sub Init( ByVal myApp As HttpApplication ) _
Implements IHttpModule.Init
 AddHandler myApp.AuthenticateRequest, AddressOf Me.OnEnter
 AddHandler myApp.EndRequest, AddressOf Me.OnLeave
End Sub

Public Sub Dispose() _
Implements IHttpModule.Dispose
End Sub

Public Sub OnEnter( s As Object, e As EventArgs )
 Dim objApp As HttpApplication
 Dim objContext As HttpContext
 Dim strPath As String

 objApp = CType( s, HttpApplication )
 objContext = objApp.Context
 strPath = objContext.Request.Path.ToLower()

 If Right( strPath, 10 ) <> "login.aspx" Then
  If objContext.Request.Params( "username" ) = Nothing Then
   objContext.Response.Redirect( "login.aspx" )
  End If
 End If
End Sub

Public Sub OnLeave( s As Object, e As EventArgs)
End Sub

End Class
End Namespace

The file in Listing 15.17 contains the code for a module named AuthModule. In the Init subroutine, the OnEnter subroutine is associated with the Application_Authenticate event, and the OnLeave subroutine is associated with the Application_EndRequest event.

NOTE

You don't actually use the OnLeave subroutine in the AuthModule module. Typically, you use OnLeave to clean up any resources that you have allocated for your module.

All the work happens in the OnEnter subroutine, which checks whether the current page is the login.aspx page. If it's not, and the parameters collection does not contain a username parameter, the user is automatically redirected to the login.aspx page.

So, if you request a page named secret like this

http://yourSite.com/secret.aspx

you are automatically redirected to the login.aspx page. However, if you request the secret page like this

http://yoursite.com/secret.aspx?username=bob

you can see the secret content in secret.aspx.

You need to compile the file in Listing 15.17 before you can use AuthModule module. To do so, execute the following command from the command line:

vbc /t:library /r:System.dll,System.Web.dll AuthModule.vb

After you compile the module, you need to move the AuthModule.dll file to your application's /bin directory.

Before you can use the module, you must add a reference to the module in the Web.Config file. The Web.Config file in Listing 15.18 contains the needed configuration settings.

Listing 15.18 Web.Config

<configuration>
 <system.web>
  <httpModules>
  <add name="AuthModule"
   type="myModules.AuthModule,AuthModule" />
  </httpModules>
 </system.web>
</configuration>

The Web.Config file in Listing 15.18 includes an httpModules section that contains the custom AuthModule module. The value of the type attribute is the name of the class and the name of the assembly.

Creating the WhosOn Application

In the following sections, you build a simple statistics application called WhosOn that uses both an HTTP handler and module. The WhosOn application displays statistics on the users of a particular page. For example, if your application contains a page at the path /myApp/Products.aspx, you can view statistics on the users who last accessed the page by requesting the page at /myApp/Products.axd (see Figure 15.6).

Figure 15.6 Output of the WhosOn statistics application.

The WhosOn page lists the time, browser type, referrer, and remote IP address for the users who last accessed the page. You can configure the number of users that the application should track per page by modifying a setting in the Web.Config file.

To create the WhosOn application, you need to create three files:

  • Web.Config—You use the Web.Config file to configure both WhosOnModule and WhosOnHandler.

  • WhosOnModule—The WhosOn module executes every time a user requests a page. The module records information on the request by adding the information to the application cache.

  • WhosOnHandler—The WhosOn handler displays statistics for a particular page. For example, requesting products.axd displays statistics on the products.aspx page.

You learn how to create each of these files in the following sections.

NOTE

You can find all the WhosOn files in the WhosOn subdirectory on the CD that accompanies this book.

Creating the WhosOn Web.Config File

You can start this example by creating the Web.Config file contained in Listing 15.19.

Listing 15.19 Web.Config

<configuration>
 <system.web>
  <httpModules>
  <add name="WhosOnModule"
   type="WhosOn.WhosOnModule,WhosOnModule" />
  </httpModules>
  <httpHandlers>
   <add verb="*" path="*.axd"
   type="WhosOn.WhosOnHandler,WhosOnHandler" />
  </httpHandlers>
 </system.web>
 <appSettings>
  <add key="whoson" value="5" />
 </appSettings>
</configuration>

The Web.Config file in Listing 15.19 adds the WhosOnModule to the current application. It associates the WhosOnHandler with all pages that end with the extension .axd. Finally, it sets the maximum number of entries tracked by WhosOnModule to the value 5.

Creating the WhosOn Module

The WhosOnModule, contained in Listing 15.20, grabs statistics for each request and adds them to the application cache.

Listing 15.20 WhosOnModule.vb

Imports System
Imports System.Web
Imports System.Collections
Imports System.Configuration
Imports Microsoft.VisualBasic

Namespace WhosOn

Public Class WhosOnModule 
Implements IHttpModule

Public Sub Init( ByVal myApp As HttpApplication ) _
Implements IHttpModule.Init
 AddHandler myApp.BeginRequest, AddressOf Me.OnEnter
End Sub

Public Sub Dispose() _
Implements IHttpModule.Dispose
End Sub

Public Sub OnEnter( s As Object, e As EventArgs )
 Dim objApp As HttpApplication
 Dim objContext As HttpContext
 Dim strPath As String
 Dim colPageStats As Queue
 Dim objStatsEntry As StatsEntry
 Dim intMaxEntries As Integer

 objApp = CType( s, HttpApplication )
 objContext = objApp.Context
 strPath = objContext.Request.Path.ToLower()

 ' Don't keep stats on .axd pages
 If Right( strPath, 4 ) = ".axd" Then
  Exit Sub
 End If 
 strPath = strPath.SubString( 0, InstrRev( strPath, "." ) - 1 )

 ' Get Max Entries From Web.Config
 intMaxEntries = cINT( ConfigurationSettings.AppSettings( "whoson" ) )

 ' Check whether Cache object exists
 colPageStats = CType( objContext.Cache( "whoson_" & strPath ), Queue )
 If colPageStats Is Nothing Then
  colPageStats = New Queue()
 End If

 ' Add Current Request to the Queue
 objStatsEntry = New StatsEntry( _
  objContext.TimeStamp, _
  objContext.Request.Browser.Type, _
  objContext.Request.UserHostName, _
  objContext.Request.ServerVariables( "HTTP_REFERER" ) ) 
 colPageStats.Enqueue( objStatsEntry )

 ' Delete Previous Entries
 If intMaxEntries <> Nothing Then
 While colPageStats.Count > intMaxEntries
  colPageStats.Dequeue()
 End While
 End If

 ' Update the Cache
 objContext.Cache( "whoson_" & strPath ) = colPageStats
End Sub

End Class

Public Class StatsEntry

Public TimeStamp As DateTime
Public BrowserType As String
Public UserHostName As String
Public Referrer As String

Public Sub New( _
 TimeStamp As DateTime, _
 BrowserType As String, _
 UserHostName As String, _
 Referrer As String )
 
 Me.TimeStamp = TimeStamp
 Me.BrowserType = BrowserType
 Me.UserHostName = UserHostName
 Me.Referrer = Referrer
End Sub

End Class

End Namespace

The WhosOn module is triggered by the Application_BeginRequest event. When this event fires, the OnEnter subroutine is executed.

The OnEnter subroutine first checks whether the current page has the extension .axd. Because you don't want to keep statistics on the statistics pages, the subroutine is exited if the current page is a statistics page.

Next, the WhosOn key from the Web.Config appSetting section is retrieved. The value of the WhosOn key is assigned to a variable named intMaxEntries.

The current page statistics are then retrieved from the application cache. The page statistics are represented in a Queue collection.

Next, the OnEnter subroutine grabs the time stamp of the current request, the browser type, the remote host name, and the referrer server variable. This information is stored in a custom class named StatsEntry.

The StatsEntry class is added to the page statistics queue. If the queue contains more than the maximum allowable number of entries, older entries are deleted.

Finally, the page statistics are inserted back into the Cache object.

Before you can use the WhosOnModule, you need to compile it. You can compile the file in Listing 15.20 by executing the following statement from the command line:

vbc /t:library /r:System.dll,System.Web.dll WhosOnModule.vb

After you compile the module, remember to copy the compiled WhosOnModule.dll file to the application /bin directory.

Creating the WhosOn Handler

The WhosOn handler, contained in Listing 15.21, displays the statistics for a particular page. You can view the output of the WhosOn handler by requesting a page with the extension .axd. For example, a request for the products.axd page would display user statistics for a page named products.aspx.

Listing 15.21 WhosOnHandler.vb

Imports System.Web
Imports System.Collections
Imports Microsoft.VisualBasic

Namespace WhosOn

Public Class WhosOnHandler 
Implements IHttpHandler

Public Sub ProcessRequest( objContext As HttpContext ) _
 Implements IHttpHandler.ProcessRequest
 
 Dim colPageStats As Queue
 Dim strPath As String
 Dim objStatsEntry As StatsEntry

 ' Get Page Path
 strPath = objContext.Request.Path
 strPath = strPath.SubString( 0, InstrRev( strPath, "." ) - 1 )

 ' Display the Stats
 colPageStats = CType( objContext.Cache( "whoson_" & strPath ), Queue )
 If Not colPageStats Is Nothing Then
 objContext.Response.Write( "<table border=1 cellpadding=4>" )
 objContext.Response.Write( "<tr><td colspan=4 bgcolor=orange>" )
 objContext.Response.Write( "<b>Who's On</b>" )
 objContext.Response.Write( "</td></tr>" )
 objContext.Response.Write( "<tr colspan=4 bgcolor=#eeeeee>" )
 objContext.Response.Write( "<th>Timestamp</th>" )
 objContext.Response.Write( "<th>Browser Type</th>" )
 objContext.Response.Write( "<th>Remote Address</th>" )
 objContext.Response.Write( "<th>Referrer</th>" )
 objContext.Response.Write( "</td></tr>" )
 For each objStatsEntry in colPageStats
  objContext.Response.Write( "<tr>" )
  objContext.Response.Write( "<td>" & objStatsEntry.TimeStamp & "&nbsp;</td>" )  
  objContext.Response.Write( "<td>" & objStatsEntry.BrowserType & "&nbsp;</td>" )  
  objContext.Response.Write( "<td>" & objStatsEntry.UserHostName & "&nbsp;</td>" )  
  objContext.Response.Write( "<td>" & objStatsEntry.Referrer & "&nbsp;</td>" )  
 Next
 objContext.Response.Write( "</table>" )
 End If 
 End Sub

 ReadOnly Property IsReusable() As Boolean _
 Implements IHttpHandler.IsReusable
  Get
   Return True
  End Get
 End Property

End Class

End Namespace

The WhosOn handler contains one long subroutine named ProcessRequest, which retrieves the item from the Cache object associated with the current page. If this item exists, it is a Queue collection. Next, the subroutine iterates through the contents of the Queue collection, displaying each statistics entry.

Before you can use the WhosOn handler, you need to compile the file in Listing 15.21. You can compile the handler by executing the following statement from the command line:

vbc /t:library /r:System.dll,System.Web.dll,WhosOnModule.dll WhosOnHandler.vb

Notice that you must reference the WhosOnModule.dll assembly because the StatsEntry class is defined there.

After you compile the handler, you need to copy the WhosOnHandler.dll file to your application's /bin directory.

You can test the WhosOn application by requesting any page from your Web site, for example:

http://localhost/default.aspx

Next, request the page using the extension .axd, rather than .aspx:

http://localhost/default.axd

Statistics for the default.aspx page are displayed.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020