Web event A web event is a derivative of the WebBaseEvent class and is used to contain information pertinent to the event raised and can often contain additional information. For example, several of the event classes that come with the system store information about the application such as its directory, the time of the event, the page in which the event occurred, and so on.
Web Event provider A Web Event provider is a special class that can subscribe to web events. When the provider receives an event, it can then store the event in a persistence medium like SQL Server or a file on disk, or it can forward the event by sending an e-mail or a text message to a cellular phone.
Events and providers are linked together in your application's Web.config file. Event types are assigned to named groups in the Web.config's <eventMappings> element. By default, ASP.NET already has several event providers defined as well as event groups.
Table 31.1 shows the web events that come with ASP.NET 2.0.
Indicates important lifetime events in an application such as startup and shutdown.
Base class for all audit-type web events.
Indicates successful authentication.
Base class for all error-type web events.
Used as a health monitoring timer. Event is raised once per heartbeatInterval as defined in the healthMonitoring Web.config section.
Base class for web events that contain process details.
Indicates a web request error.
Base class for all web events related to requests.
Indicates a successful security event.
Indicates a view state failure.
ASP.NET 2.0 also contains several default web event providers. Those providers are described in Table 31.2.
Stores web event data in the system event log.
Stores web event data in SQL Server. Defaults to the App_Data folder and a SQL Express database but can be configured for other locations.
Sends web events to WMI, converting them into WMI events.
These providers send e-mail in response to web events.
Web event data is passed to the ASP.NET page tracing subsystem.
By default, very little of this system is configured. If you don't specify any other web event information in your application's Web.config file, your application will send the All Errors and Failure Audits events to the EventLogWebEventProvider class.
Using the health monitoring system really boils down to manipulating the Web.config file to determine which events are handled by which event providers. As mentioned earlier, errors and failure audits are sent to the system event log by default. Using the Web.config file, you can use additional ASP.NET Web Event providers to handle additional event types.
This section shows you how to use a SQL Server 2005 database table as the destination for error events such as unhandled exceptions. Although the system event log might be handy in a few circumstances, storing all application errors in a central location that can be queried from remote locations is extremely useful. For example, if your application is running in a web farm scenario (multiple web servers hosting the same application), you will want all of the errors to be accessible in the same place and tagged with the name of the machine that originated the error. Logging errors using the SqlWebEventProvider does exactly that.
To start, create a new ASP.NET web application and add a Web.config file to the project. The SQL Web Event provider uses a table called aspnet_WebEvent_Events that is created when you create an application services database using the aspnet_regsql.exe tool.
Listing 31.1 contains the modified Web.config that will utilize the SQL Web Event provider.
When you run the application, you will get the application exception and VS 2005 will break. Continue execution and then wait a minute or two. Because the SqlWebEventProvider class uses a buffered system, the error won't appear within the database immediately. Figure 31.1 shows the contents of the aspnet_WebEvent_Events table after an error occurs.
Figure 31.1. Storing web errors in SQL Server.
Also shown in this figure are lifetime events. Lifetime events indicate significant changes that occur in an application's lifetime such as application startup and shutdown. This information can be important when diagnosing problems with a production server. To support lifetime events in your application, change the preceding Web.config to the one shown in Listing 31.2.
This configuration file adds a new entry to the <eventMappings> section indicating that events in the group "Lifetime" are of the type WebApplicationLifetimeEvent. The <rules> section indicates that all events in the group "Lifetime" are to be handled by the SqlWebEventHandler class. This provides the necessary hooks to get information like application startup and shutdown stored in the SQL Server database.
If you are a tinkerer or just curious, you might try to raise these events manually instead of letting ASP.NET handle them on your behalf. This can't be done, however. All of the default web event classes have an internal protection level so that they cannot be instantiated by code outside the System.Web assembly. This is done deliberately to ensure that only the ASP.NET engine can manually raise the default events. If you want to raise custom events, the next section, "Creating Custom Events," should prove helpful.
If your event requires the storage of data that is not already being stored by any of the existing event classes, you should create your own event.
If you need programmatic control over when to signal the event, you can create your own and inherit from the event you want to manually signal. Keep in mind, however, that ASP.NET already does an excellent job of signaling events at the appropriate time, and you should use the existing events whenever possible.
A common pitfall that a lot of people run into is that they create a web event that inherits from an existing base event, and then manually fire that event in the same place where ASP.NET would have automatically fired it. For example, if a developer overrides the WebErrorEvent and calls the Raise() method within the catch portion of a TRy/catch block, she is essentially reinventing the wheel. In this situation, the only reason a developer should take manual control over raising such error events is if the developer needs to store more information in the event than the default ASP.NET WebErrorEvent class provides.
The next sample will illustrate the use of a custom web event that will get signaled when a user of a research department's website requests a search. As you'll see in the next section on creating a custom provider, this request can then either be handled automatically via web services or dispatched to a research department employee.
Add a new Class Library project to the solution that contains the website from the previous samples. Add a reference to the System.Web Assembly and add a class to the project called AsyncSearchRequest. Listing 31.3 shows the class that inherits from WebBaseEvent.
The constructors were created so that you can see where you can inject your own code into the instantiation process. The FormatCustomEventDetails method is used to provide additional text data that will be logged with the event when sent to a provider.
One of the most powerful features of the new ASP.NET Web Management system is that you can plug any of your custom events into any of the existing event providers or any custom providers that you or a third party create.
Listing 31.4 contains a new Web.config for the web application that associates the newly created custom event with the SQL Server Web Event provider.
To illustrate how to create a custom Web Event provider, this section will show you how to create a Research Dispatch provider that handles AsyncSearchWebEvent events and dispatches them accordingly. To create a basic Web Event provider, create a class that inherits from the base class BufferedWebEventProvider (you can create an unbuffered one, but this sample uses a buffered provider to provide a comparison with the buffered SqlWebEventProvider class). To see this in action, add a new class called SearchWebEventProvider to the class library that contains the AsyncSearchWebEvent class. This class is shown in Listings 31.5.
The code for the provider itself isn't very complex. The complexity can come from choosing the storage medium or notification medium used when handling the event. The preceding sample shows how you can create a simple provider shell to be used with the search event.