Using HttpModules instead of Global.asax

Discussion in 'ASP .Net' started by Anonieko, Jun 15, 2006.

  1. Anonieko

    Anonieko Guest

    Global.asax? Use HttpModules Instead!
    In a previous post, I talked about HttpHandlers - an underused but
    incredibly useful feature of ASP.NET. Today I want to talk about
    HttpModules, which are probably more common than HttpHandlers, but
    could still stand to be advertised a bit more.

    HttpModules are incredibly easy to explain, so this will hopefully be a
    short-ish post. Simply put, HttpModules are portable versions of the
    global.asax. So, in your HttpModule you'll see things like
    BeginRequest, OnError, AuthenticateRequest, etc. Actually, since
    HttpModules implement IHttpModule, you actually only get Init (and
    Dispose if you have any cleanup to do). The Init method passes in the
    HttpApplication which lets you hook into all of those events. For
    example, I have an ErrorModule that I use on most projects:

    using System;
    using System.Web;
    using log4net;

    namespace Fuel.Web
    {
    public class ErrorModule : IHttpModule
    {
    #region IHttpModule Members
    public void Init(HttpApplication application)
    {
    application.Error += new EventHandler(application_Error);
    }
    public void Dispose() { }
    #endregion

    public void application_Error(object sender, EventArgs e)
    {
    //handle error
    }
    }
    }

    Now, the code in my error handler is pretty simple:

    HttpContext ctx = HttpContext.Current;
    //get the inner most exception
    Exception exception;
    for (exception = ctx.Server.GetLastError(); exception.InnerException !=
    null; exception = exception.InnerException) { }
    if (exception is HttpException &&
    ((HttpException)exception).GetHttpCode() == 404)
    {
    logger.Warn("A 404 occurred", exception);
    }
    else
    {
    logger.Error("ErrorModule caught an unhandled exception", exception);
    }

    I'm just using a log4net logger to log the exception, if it's a 404 I'm
    just logging it as a warning.

    You can do this just as easily with a global.asax, but those things
    aren't reusable across projects. That of course means that you'll end
    up duplicating your code and making it hard to manage. With my
    ErrorModule class, I just put it in a DLL, drop it in my bin folder and
    add a couple lines to my web.config under <system.web>:

    <httpModules>
    <add name="ErrorModule" type="Fuel.Web.ErrorModule, Fuel.Web" />
    </httpModules>

    And voila, I have a global error in place.

    In almost all cases, you should go with HttpModules over global.asax
    because they are simply more reusable. As another example, my
    localization stuff uses an HttpModule as the basis for adding a
    multilingual framework to any application. Simply drop the DLL in the
    bin and add the relevant line in your web.config and you're on your
    way. Here's the important code from that module:

    public void Init(HttpApplication context)
    {
    context.BeginRequest += new EventHandler(context_BeginRequest);
    }
    public void Dispose() {}
    private void context_BeginRequest(object sender, EventArgs e)
    {
    HttpRequest request = ((HttpApplication) sender).Request;
    HttpContext context = ((HttpApplication)sender).Context;
    string applicationPath = request.ApplicationPath;
    if(applicationPath == "/")
    {
    applicationPath = string.Empty;
    }
    string requestPath =
    request.Url.AbsolutePath.Substring(applicationPath.Length);
    //just a function that parses the path for a culture and sets the
    CurrentCulture and CurrentUICulture
    LoadCulture(ref requestPath);
    context.RewritePath(applicationPath + requestPath);
    }

    If you are developing a shrink-wrap product, you don't have a choice
    but to use HttpModules, because the last thing you want is to ship a
    global.asax which the user must use, overwriting the code in his own
    global.asax.

    The only time you want to use Global.asax is when using OutputCaching
    with the VaryByCustom property. As far as I know, the
    GetVaryByCustomString function _must_ be placed in the global.asax
    file.

    Anyways, switching from Global.asax to HttpModules is pretty
    straightforward. So I encourage you to look at where it makes sense
    (ie, where you see the potential for reuse across applications) and
    make it so.
     
    Anonieko, Jun 15, 2006
    #1
    1. Advertising

  2. Is there a reason you're trying to pass off someone else's work as your own?
    As the author for these three pieces, I'm glad you saw value in what I
    wrote, but don't appreciate having it spammed in a help newsgroup (which I
    happen to spend a lot of time in) and I don't appreciate you not linking
    back to the original content.

    http://codebetter.com/blogs/karlseguin/

    --
    http://www.openmymind.net/
    http://www.fuelindustries.com/


    "Anonieko" <> wrote in message
    news:...
    > Global.asax? Use HttpModules Instead!
    > In a previous post, I talked about HttpHandlers - an underused but
    > incredibly useful feature of ASP.NET. Today I want to talk about
    > HttpModules, which are probably more common than HttpHandlers, but
    > could still stand to be advertised a bit more.
    >
    > HttpModules are incredibly easy to explain, so this will hopefully be a
    > short-ish post. Simply put, HttpModules are portable versions of the
    > global.asax. So, in your HttpModule you'll see things like
    > BeginRequest, OnError, AuthenticateRequest, etc. Actually, since
    > HttpModules implement IHttpModule, you actually only get Init (and
    > Dispose if you have any cleanup to do). The Init method passes in the
    > HttpApplication which lets you hook into all of those events. For
    > example, I have an ErrorModule that I use on most projects:
    >
    > using System;
    > using System.Web;
    > using log4net;
    >
    > namespace Fuel.Web
    > {
    > public class ErrorModule : IHttpModule
    > {
    > #region IHttpModule Members
    > public void Init(HttpApplication application)
    > {
    > application.Error += new EventHandler(application_Error);
    > }
    > public void Dispose() { }
    > #endregion
    >
    > public void application_Error(object sender, EventArgs e)
    > {
    > //handle error
    > }
    > }
    > }
    >
    > Now, the code in my error handler is pretty simple:
    >
    > HttpContext ctx = HttpContext.Current;
    > //get the inner most exception
    > Exception exception;
    > for (exception = ctx.Server.GetLastError(); exception.InnerException !=
    > null; exception = exception.InnerException) { }
    > if (exception is HttpException &&
    > ((HttpException)exception).GetHttpCode() == 404)
    > {
    > logger.Warn("A 404 occurred", exception);
    > }
    > else
    > {
    > logger.Error("ErrorModule caught an unhandled exception", exception);
    > }
    >
    > I'm just using a log4net logger to log the exception, if it's a 404 I'm
    > just logging it as a warning.
    >
    > You can do this just as easily with a global.asax, but those things
    > aren't reusable across projects. That of course means that you'll end
    > up duplicating your code and making it hard to manage. With my
    > ErrorModule class, I just put it in a DLL, drop it in my bin folder and
    > add a couple lines to my web.config under <system.web>:
    >
    > <httpModules>
    > <add name="ErrorModule" type="Fuel.Web.ErrorModule, Fuel.Web" />
    > </httpModules>
    >
    > And voila, I have a global error in place.
    >
    > In almost all cases, you should go with HttpModules over global.asax
    > because they are simply more reusable. As another example, my
    > localization stuff uses an HttpModule as the basis for adding a
    > multilingual framework to any application. Simply drop the DLL in the
    > bin and add the relevant line in your web.config and you're on your
    > way. Here's the important code from that module:
    >
    > public void Init(HttpApplication context)
    > {
    > context.BeginRequest += new EventHandler(context_BeginRequest);
    > }
    > public void Dispose() {}
    > private void context_BeginRequest(object sender, EventArgs e)
    > {
    > HttpRequest request = ((HttpApplication) sender).Request;
    > HttpContext context = ((HttpApplication)sender).Context;
    > string applicationPath = request.ApplicationPath;
    > if(applicationPath == "/")
    > {
    > applicationPath = string.Empty;
    > }
    > string requestPath =
    > request.Url.AbsolutePath.Substring(applicationPath.Length);
    > //just a function that parses the path for a culture and sets the
    > CurrentCulture and CurrentUICulture
    > LoadCulture(ref requestPath);
    > context.RewritePath(applicationPath + requestPath);
    > }
    >
    > If you are developing a shrink-wrap product, you don't have a choice
    > but to use HttpModules, because the last thing you want is to ship a
    > global.asax which the user must use, overwriting the code in his own
    > global.asax.
    >
    > The only time you want to use Global.asax is when using OutputCaching
    > with the VaryByCustom property. As far as I know, the
    > GetVaryByCustomString function _must_ be placed in the global.asax
    > file.
    >
    > Anyways, switching from Global.asax to HttpModules is pretty
    > straightforward. So I encourage you to look at where it makes sense
    > (ie, where you see the potential for reuse across applications) and
    > make it so.
    >
     
    Karl Seguin [MVP], Jun 15, 2006
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?YmNoYXJsZXM=?=

    global.asax and global.asax.cs

    =?Utf-8?B?YmNoYXJsZXM=?=, Oct 4, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    863
    =?Utf-8?B?YmNoYXJsZXM=?=
    Oct 5, 2004
  2. tshad

    HTTPModules vs Global.asax

    tshad, May 3, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    4,991
    Karl Seguin [MVP]
    May 3, 2006
  3. Mark Rae

    Global.asax / Global.asax.cs in v2

    Mark Rae, May 23, 2006, in forum: ASP .Net
    Replies:
    6
    Views:
    3,186
    Mark Rae
    May 23, 2006
  4. =?Utf-8?B?Tm9yZW1hYw==?=

    Insert into instead of add to the HttpModules pipeline

    =?Utf-8?B?Tm9yZW1hYw==?=, Mar 9, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    497
    Steven Cheng[MSFT]
    Mar 14, 2007
  5. OK
    Replies:
    5
    Views:
    628
    Peter Bromberg [C# MVP]
    Nov 26, 2007
Loading...

Share This Page