Friday, August 1, 2014

The handlers and modules in Web.config!

I really haven't thought that much about what the modules and handlers do. I experimented with them some today however. I set up system.webServer in the configuration of Web.config to hold the following:

<system.webServer>
   <modules>
      <add name="SessionTimeout" type="HandleThis.Magic.LifeAndDeathModule"
            preCondition="managedHandler" />
   </modules>
   <handlers>
      <add name="LifeAndDeathHandler" verb="*" path="Speak.ashx"
            type="HandleThis.Magic.LifeAndDeathHandler" />
   </handlers>
</system.webServer>

 
 

I believe this would work just fine in system.web too, but of course system.web is just for IIS6 hosting. Let's look at what our token module and handler do. Here is the module first:

using System;
using System.Runtime.Caching;
using System.Web;
namespace HandleThis.Magic
{
   public class LifeAndDeathModule : IHttpModule
   {
      public void Init(HttpApplication httpApplication)
      {
         CacheSomething("life", "I live! ");
      }
      
      public void Dispose()
      {
         CacheSomething("death", "I die! ");
      }
      
      private void CacheSomething(string key, string value)
      {
         if (MemoryCache.Default[key] != null)
         {
            MemoryCache.Default.Remove(key);
         }
         CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
         cacheItemPolicy.AbsoluteExpiration = DateTime.Now +
               TimeSpan.FromMinutes(30);
         MemoryCache.Default.Add(new CacheItem(key, value), cacheItemPolicy);
      }
   }
}

 
 

The modules will run all the time whenever one spins up the application or whenever one just changes the URL within the application. Therefore, you can sort of do some AOP stuff within modules. For example, if I have a web form with a code behind like so:

using System;
using System.Runtime.Caching;
using System.Web.UI;
namespace HandleThis
{
   public partial class _Default : Page
   {
      public string MyState;
      
      protected void Page_Load(object sender, EventArgs e)
      {
         MyState = MemoryCache.Default["life"] as string +
               MemoryCache.Default["death"];
      }
   }
}

 
 

...I may in the web form expose some of the stuff my module put in the cache by just using some markup like this:

<h1><%= MyState %></h1>

 
 

When the app first spins up the H1 tag will say "I live!" and after some time has passed and the garbage collector has done its thing one may refresh the browser and instead see "I live! I die!" There will never be a time when at the very least "I live!" is not displayed. In setting breakpoints, I witnessed the application, upon spinning up, call the Init method on the module three times before the Page_Load method on the web form's code behind (the code behind for Default.aspx, the default first web form loaded) was called. Our handler will not run automatically by itself like our module so we must call out to it. Putting a script tag like this in our web form will do the trick:

<script src="http://localhost:65413/Speak.ashx?instructions=yell" type="text/javascript">
</script>

 
 

Here is our handler:

using System.Runtime.Caching;
using System.Web;
namespace HandleThis.Magic
{
   public class LifeAndDeathHandler : IHttpHandler
   {
      public void ProcessRequest(HttpContext httpContext)
      {
         string instructions = httpContext.Request.QueryString["instructions"];
         string message = MemoryCache.Default["life"] as string +
               MemoryCache.Default["death"];
         if (instructions == "yell") message = message.ToUpper();
         httpContext.Response.Write("alert('" + message + "');");
      }
      
      public bool IsReusable
      {
         get { return false; }
      }
   }
}

 
 

As you can see, it will return some JavaScript for the script tag!

No comments:

Post a Comment