Registering HttpHandlers
After you have created a custom HttpHandler you must configure ASP.NET to map incoming HTTP requests for specific URLs to your handler. The following procedure describes the steps required.
To register an HttpHandler
- Compile and deploy the .NET class for the HttpHandler in the \bin directory under the application's virtual root.
- Register the HttpHandler, synchronous or asynchronous, in the application's Web.config configuration file. The following example maps all HTTP requests to the classes
MyHandler.NewandMyHandler.Finin the assemblyMyHandlerthat is in the fileMyhandler.dll.<configuration> <system.web> <httpHandlers> <add verb="*" path="MyHandler.New" type="MyHandler.New, MyHandlerAssembly" /> <add verb="*" path="*.myNewFileNameExtension" type="MyHandler.Fin, MyHandlerAssembly" /> </httpHandlers> <system.web> </configuration>Entries within the <httpHandlers> configuration section have three attributes, as shown in the following table.
Attribute Description Path The path attribute can contain either a single URL path or a simple wildcard string (for example, *.aspx). Type Specifies a comma-separated class/assembly combination. ASP.NET searches for the assembly DLL first in the application's private \bin directory and then in the system assembly cache. Verb The verb list can be either a comma-separated list of HTTP methods (for example, "GET, PUT, POST") or a start-script mapping (for example, the wildcard character * [an asterisk]). - Ensure that the HttpHandler file name extension is registered within Internet Information Services (IIS).
HttpHandler Examples
This section provides the following code examples:
Synchronous HttpHandler
The following code demonstrates how to process requests for the specific MyApp.MyHello URL within an ASP.NET application. Next, the configuration file changes required to register the HttpHandler are shown.
using System.Web; public class HelloWorldHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpRequest Request = context.Request; HttpResponse Response = context.Response; // A file ending in .MyHello need not exist. This handler executes // whenever a file ending in .MyHello is requested. Response.Write("<html>"); Response.Write("<body>"); Response.Write("<h1> Hello from Synchronous custom handler. </h1>"); Response.Write("</body>"); Response.Write("</html>"); } public bool IsReusable { // To enable pooling, return true here. // This keeps the handler in memory. get { return false; } } } [Visual Basic] Imports System.Web Public Class HelloWorldHandler Implements IHttpHandler Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest Dim request As HttpRequest = context.Request Dim response As HttpResponse = context.Response ' A file named ending in .MyHello need not exist. This handler ' executes whenever a file ending in .MyHello is requested. response.Write("<html>") response.Write("<body>") response.Write("<h1> Hello from Synchronous custom handler. </h1>") response.Write("</body>") response.Write("</html>") End Sub Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable Get Return False End Get End Property End Class
Register your custom HttpHandler by creating an entry in Web.config as follows:
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.MyHello"
type="HelloWorldHandler,httpruntime" />
</httpHandlers>
</system.web>
</configuration>
Asynchronous HttpHandler
The following code demonstrates how to register and process requests for the specific *.MyAsynch URL within an ASP.NET application. In this case, the handler launches a time-consuming process, sending a response to the user at several points to indicate progress. Next, the configuration file changes required to register the HttpHandler are shown.
using System; using System.Web; using System.Threading; namespace Handlers { class AsynchHandler : IHttpAsyncHandler { private HttpContext _context; public bool IsReusable { get { // To enable pooling, return true here. // This keeps the handler in memory. return false; } } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { // Now do something that might take a while. MyAsynchOperation asynch = new MyAsynchOperation(cb, context); asynch.KickOffThread(); context.Response.Write("BeginProcessRequest. Just kicked off a Thread.<br>"); context.Response.Flush(); // Signal the application that asynchronous // processing is being performed. SomeResult asynchForBegin = new SomeResult(); // Processing is not synchronous. asynchForBegin.SetSynch(false); // Processing is not complete. asynchForBegin.SetCompleted(false); _context = context; return new SomeResult(); } public void EndProcessRequest(IAsyncResult result) { _context.Response.Write("EndProcessRequest called.<br>"); } // This method is required but is not called. public void ProcessRequest(HttpContext context) { } }//end class public class SomeResult : IAsyncResult { /* An instance of this class is returned to the application. This class lets the application know how the BeginEventHandler method has been handled. The application checks the CompletedSynchronously method. */ private bool _blnIsCompleted = false; private Mutex myMutex = null; private Object myAsynchStateObject = null; private bool _blnCompletedSynchronously = false; public void SetCompleted(bool blnTrueOrFalse) { _blnIsCompleted = blnTrueOrFalse; } public void SetSynch(bool blnTrueOrFalse) { _blnCompletedSynchronously = blnTrueOrFalse; } public bool IsCompleted { // This is not called by the application. // However, set it to true. get { return _blnIsCompleted; } } public WaitHandle AsyncWaitHandle { // The application does not call this method. get { return myMutex; } } public Object AsyncState { // The application does not call this method because // null is passed in as the last parameter to // BeginEventHandler. get { return myAsynchStateObject; } } public bool CompletedSynchronously { // The application wants to know if this is synchronous. // Return true if the Begin method was called synchronously. get { return _blnCompletedSynchronously; } } } } [Visual Basic] Imports System Imports System.Web Imports System.Threading Namespace handler Public Class AsynchHandler Implements IHttpAsyncHandler Private _context As HttpContext Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpAsyncHandler.IsReusable Get Return False End Get End Property Public Function BeginProcessRequest(ByVal context As System.Web.HttpContext, ByVal cb As System.AsyncCallback, ByVal extraData As Object) As System.IAsyncResult Implements System.Web.IHttpAsyncHandler.BeginProcessRequest Dim asynch As New MyAsynchOperation(cb, context) asynch.KickOffThread() context.Response.Write("BeginProcessRequest. Just kicked off a Thread.<br>") context.Response.Flush() ' Signal the application that asynchronous ' processing is being performed. Dim asynchForBegin As New SomeResult() ' Processing is not synchronous. asynchForBegin.SetSynch(False) ' Processing is not complete. asynchForBegin.SetCompleted(False) _context = context Return New SomeResult() End Function Public Sub EndProcessRequest(ByVal result As System.IAsyncResult) Implements System.Web.IHttpAsyncHandler.EndProcessRequest _context.Response.Write("EndProcessRequest called.<br>") End Sub Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpAsyncHandler.ProcessRequest ' Ths is required but is not called. End Sub End Class Class SomeResult Implements IAsyncResult Private _blnIsCompleted As Boolean = False Private myMutex As Mutex = Nothing Private myAsynchStateObject As Object = Nothing Private _blnCompletedSynchronously As Boolean = False Public Sub SetCompleted(ByVal blnTrueOrFalse As Boolean) _blnIsCompleted = blnTrueOrFalse End Sub Public Sub SetSynch(ByVal blnTrueOrFalse As Boolean) _blnCompletedSynchronously = blnTrueOrFalse End Sub Public ReadOnly Property AsyncState() As Object Implements System.IAsyncResult.AsyncState Get Return myAsynchStateObject End Get End Property Public ReadOnly Property AsyncWaitHandle() As System.Threading.WaitHandle Implements System.IAsyncResult.AsyncWaitHandle Get Return myMutex End Get End Property Public ReadOnly Property CompletedSynchronously() As Boolean Implements System.IAsyncResult.CompletedSynchronously Get Return _blnCompletedSynchronously End Get End Property Public ReadOnly Property IsCompleted() As Boolean Implements System.IAsyncResult.IsCompleted Get Return _blnIsCompleted End Get End Property End Class End Namespace
Register your custom asynchronous HttpHandler by creating an entry in Web.config as follows:
<configuration>
<system.web>
<httpHandlers>
<add verb="GET,POST" path="*.MyAsynch"
type="Handlers.AsynchHandler, Handlers" />
</httpHandlers>
</system.web>
</configuration>
See Also
HTTP Runtime Support | ASP.NET Request Processing | Creating HttpHandlers | HttpModules | Handling and Raising Events