<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Invested Development &#187; HttpModule</title>
	<atom:link href="http://devblog.stuartthompson.net/tag/httpmodule/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.stuartthompson.net</link>
	<description>Thoughtful Approaches to Software Architecture</description>
	<lastBuildDate>Tue, 18 Oct 2011 17:08:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Http Modules</title>
		<link>http://devblog.stuartthompson.net/2010/02/http-modules/</link>
		<comments>http://devblog.stuartthompson.net/2010/02/http-modules/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 20:07:31 +0000</pubDate>
		<dc:creator>stuartthompson</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[HttpModule]]></category>

		<guid isPermaLink="false">http://devblog.stuartthompson.net/2010/02/http-modules/</guid>
		<description><![CDATA[The .NET framework provides several mechanisms for extending the behaviors of web pages and other endpoints. One such technique is the http module. Modules are often either overlooked as a solution or are considered too heavyweight or scary for use. This is unfortunate as they are a powerful item in the ASP.NET development toolbox. An [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">The <a title="Microsoft .NET Framework" href="http://www.microsoft.com/net/" target="_blank">.NET framework</a> provides several mechanisms for extending the behaviors of web pages and other endpoints. One such technique is the http module. Modules are often either overlooked as a solution or are considered too heavyweight or scary for use. This is unfortunate as they are a powerful item in the ASP.NET development toolbox.</p>
<p align="justify">An <a title="Http Modules on MSDN" href="http://msdn.microsoft.com/en-us/library/zec9k340(VS.71).aspx" target="_blank">http module</a> is a single unit of code that is executed as part of the web request pipeline. When a web request is received, the list of registered modules are afforded the opportunity to inject themselves at several stages in the execution pipeline. Each module has the opportunity to inspect or modify parts of the request before or after it is processed. This makes them a powerful mechanism for attaching custom behaviors. Modules also have a flexible activation model as they can be attached or detached via configuration allowing them to be enabled or disabled at will without affecting a production site.</p>
<p align="justify">The full source code for this example can be found <a title="Links to the http module sample in the code repository at stuartthompson.net." href="http://code.stuartthompson.net/public/Samples/Http%20Modules/">here</a>.</p>
<p align="justify"><strong>How to Create an HttpModule</strong>    <br />The ASP.NET Module type is in the Web category under the Add New Item dialog.</p>
<p><a href="http://devblog.stuartthompson.net/wp-content/uploads/2010/02/241229_tmp6C6D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="241@229_tmp6C6D" border="0" alt="241@229_tmp6C6D" src="http://devblog.stuartthompson.net/wp-content/uploads/2010/02/241229_tmp6C6D_thumb.png" width="244" height="171" /></a></p>
<p align="justify">Remove the default sample code that is included in the template. The LogContext event handler is implemented in the template for demonstration purposes but is not used in this example. Your class should now look similar to the following:</p>
</p>
<pre class="brush:csharp">using System;
using System.Web;

namespace ModuleWebApp
{

    ///
<summary>
    /// Custom http module.
    /// </summary>

    public class MyNewModule : IHttpModule
    {

        #region IHttpModule Members

        public void Dispose() {}

        ///
<summary>
        /// Initializes the module.
        /// </summary>

        /// &lt;param name=&quot;context&quot;&gt;The application context.&lt;/param&gt;
        public void Init(HttpApplication context)
        {

        }

        #endregion

    }
}</pre>
</p>
<p align="justify"><strong>Initializing the Module</strong></p>
<p>Modules perform work by registering handlers for events in the request execution pipeline such as BeginRequest and EndRequest. It is within the event handlers that they perform their task. In the example below, the Init method is used to register handlers for the BeginRequest and EndRequest events.</p>
</p>
<pre class="brush:csharp">///
<summary>
/// Raised when the module is initialized.
/// </summary>

/// &lt;param name=&quot;context&quot;&gt;The application context.&lt;/param&gt;
public void Init(HttpApplication context)
{
    context.BeginRequest += new EventHandler(context_BeginRequest);
    context.EndRequest += new EventHandler(context_EndRequest);
}</pre>
</p>
<p align="justify"><strong>Implementing the Event Handlers and Finishing the Module</strong></p>
<p>Next provide implementations for the event handlers. This example module is going to calculate and display the time it takes to execute a page within the application. The code example below is for the completed module class. It contains the following changes:</p>
<ul>
<li>Declaration of a dictionary of stopwatches that stores the execution timers. </li>
<li>Implementation of the BeginRequest and EndRequest handlers to start and stop the timers. </li>
<li>Instantiation of the dictionary of timers in the Init method. </li>
</ul>
<pre class="brush:csharp">using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Web;

namespace ModuleWebApp
{

    /// &lt;summary&gt;
    /// A custom http module used to time request execution.
    /// &lt;/summary&gt;
    public class RequestTimer : IHttpModule
    {

        #region IHttpModule Members

        public void Dispose() { }

        /// &lt;summary&gt;
        /// Raised when the module is initialized.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;context&quot;&gt;The application context.&lt;/param&gt;
        public void Init(HttpApplication context)
        {
            _timers = new Dictionary&lt;Guid, Stopwatch&gt;();

            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.EndRequest += new EventHandler(context_EndRequest);
        }

        #endregion

        #region Event Handlers

        /// &lt;summary&gt;
        /// Raised when the request begins.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;sender&quot;&gt;The source of the event; the &lt;see cref=&quot;System.Web.HttpApplication&quot; /&gt;.&lt;/param&gt;
        /// &lt;param name=&quot;e&quot;&gt;An &lt;see cref=&quot;System.EventsArgs&quot;/&gt; that contains event data.&lt;/param&gt;
        protected void context_BeginRequest(object sender, EventArgs e)
        {
            Guid timerId = Guid.NewGuid();
            Stopwatch timer = new Stopwatch();
            _timers.Add(timerId, timer);

            HttpContext.Current.Items.Add(EXECUTION_TIMER_KEY, timerId.ToString());

            timer.Start();
        }

        /// &lt;summary&gt;
        /// Raised when the request ends.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;sender&quot;&gt;The source of the event; the &lt;see cref=&quot;System.Web.HttpApplication&quot; /&gt;.&lt;/param&gt;
        /// &lt;param name=&quot;e&quot;&gt;An &lt;see cref=&quot;System.EventsArgs&quot;/&gt; that contains event data.&lt;/param&gt;
        protected void context_EndRequest(object sender, EventArgs e)
        {
            string timerId = HttpContext.Current.Items[EXECUTION_TIMER_KEY] as string;

            if (String.IsNullOrEmpty(timerId))
                return;

            Stopwatch timer = _timers[new Guid(timerId)];
            if (timer == null)
                return;

            timer.Stop();

            double elapsedSeconds = (timer.ElapsedMilliseconds) / (double)1000;

            HttpContext.Current.Response.Write(
                String.Format(
                    &quot;Request executed in {0} seconds ({1} ticks).&quot;,
                    elapsedSeconds.ToString(),
                    timer.ElapsedTicks.ToString()));
        }

        #endregion

        #region Fields

        /// &lt;summary&gt;
        /// The collection of execution timers.
        /// &lt;/summary&gt;
        private Dictionary&lt;Guid, Stopwatch&gt; _timers;

        #endregion

        #region Constants

        private const string EXECUTION_TIMER_KEY = &quot;__ExecutionTimer_Id&quot;;

        #endregion

    }

}</pre>
</p>
<p align="justify">Some of the concepts used here are beyond the scope of this discussion. Research the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx">Stopwatch</a> class for more information on how to use timers. See the <a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx">HttpContext</a> class to learn more about <a href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.aspx">request</a> and <a href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.aspx">response</a> objects. </p>
<p align="justify"><strong>Registering the Module</strong></p>
<p>The final step is to register the module so that it is instantiated and executed on every request. This is done via the web.config file. The &lt;system.web&gt; section contains an &lt;httpModules&gt; section. The registration configuration line for the module should be added to the &lt;httpModules&gt; section as shown below:</p>
</p>
<pre class="brush:xml"><system.web>
	<!-- ... other configuration information ... -->
	<httpmodules>
		<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
		<add name="CustomUrlParser" type="ModuleWebApp.CustomUrlParser, ModuleWebApp" />
    <add name="RequestTimer" type="ModuleWebApp.RequestTimer, ModuleWebApp" />
	</httpmodules>
</system.web></pre>
</p>
<p align="justify">That&#8217;s it! Running the web application should display the default.aspx page, which now shows the execution time in elapsed seconds (and ticks). This information is displayed at the end of every web request so it works on every page in the system. If you inspect the context_EndRequest handler you can see the following lines: </p>
<pre class="brush:csharp">
HttpContext.Current.Response.Write(
	String.Format(
		&quot;Request executed in {0} seconds ({1} ticks).&quot;,
		elapsedSeconds.ToString(),
		timer.ElapsedTicks.ToString()));</pre>
</p>
<p align="justify">The HttpContext class exposes the current Request and Response. These are the http request and response that are received from and sent to the client respectively. The execution time was displayed on the page because this handler wrote to the response object after the request had finished executing. The timer was started when the request started and stopped when the request ended. The time taken for the page to performing its processing and the request to finish is then displayed in the response. It is in this way that modules interact with all requests in the system and provide global level behaviors that are attached via configuration. </p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/home/?status=Http+Modules%3A+http%3A%2F%2Fdevblog.stuartthompson.net%2F%3Fp%3D128" title="Post to Twitter"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter-micro3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://buzz.yahoo.com/buzz?targetUrl=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;headline=Http+Modules" title="Post to Yahoo Buzz"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/buzz/tt-buzz-micro3.png" alt="Post to Yahoo Buzz" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;title=Http+Modules" title="Post to Delicious"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious-micro3.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;title=Http+Modules" title="Post to Digg"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/digg/tt-digg-micro3.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;t=Http+Modules" title="Post to Facebook"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook-micro3.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;title=Http+Modules" title="Post to Reddit"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit-micro3.png" alt="Post to Reddit" /></a> <a target="_blank" class="tt" href="http://stumbleupon.com/submit?url=http://devblog.stuartthompson.net/2010/02/http-modules/&amp;title=Http+Modules" title="Post to StumbleUpon"><img class="nothumb" src="http://devblog.stuartthompson.net/wp-content/plugins/tweet-this/icons/en/su/tt-su-micro3.png" alt="Post to StumbleUpon" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://devblog.stuartthompson.net/2010/02/http-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

